Merge pull request #63928 from deads2k/cli-61-apiversion-protection
Automatic merge from submit-queue (batch tested with PRs 63920, 63716, 63928, 60553, 63946). 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>. add protection for missing apiversion so we never serialize a bad object we need the json and yaml printers to fail if they are going to serialize a thing that is missing apiversion and kind information. This adds a simple check for it. @kubernetes/sig-cli-maintainers /assign @juanvallejo /assign @soltysh ```release-note NONE ```
This commit is contained in:
		| @@ -31,12 +31,12 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	"k8s.io/apimachinery/pkg/util/json" | 	"k8s.io/apimachinery/pkg/util/json" | ||||||
|  |  | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl" | 	"k8s.io/kubernetes/pkg/kubectl" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| ) | ) | ||||||
| @@ -111,7 +111,7 @@ var ( | |||||||
|  |  | ||||||
| func NewAnnotateOptions(ioStreams genericclioptions.IOStreams) *AnnotateOptions { | func NewAnnotateOptions(ioStreams genericclioptions.IOStreams) *AnnotateOptions { | ||||||
| 	return &AnnotateOptions{ | 	return &AnnotateOptions{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("annotated", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("annotated").WithTypeSetter(scheme.Scheme), | ||||||
|  |  | ||||||
| 		RecordFlags: genericclioptions.NewRecordFlags(), | 		RecordFlags: genericclioptions.NewRecordFlags(), | ||||||
| 		Recorder:    genericclioptions.NoopRecorder{}, | 		Recorder:    genericclioptions.NoopRecorder{}, | ||||||
|   | |||||||
| @@ -42,7 +42,6 @@ import ( | |||||||
| 	"k8s.io/client-go/dynamic" | 	"k8s.io/client-go/dynamic" | ||||||
| 	scaleclient "k8s.io/client-go/scale" | 	scaleclient "k8s.io/client-go/scale" | ||||||
| 	oapi "k8s.io/kube-openapi/pkg/util/proto" | 	oapi "k8s.io/kube-openapi/pkg/util/proto" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | 	api "k8s.io/kubernetes/pkg/apis/core" | ||||||
| 	"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" | ||||||
| @@ -132,7 +131,7 @@ func NewApplyOptions(ioStreams genericclioptions.IOStreams) *ApplyOptions { | |||||||
| 	return &ApplyOptions{ | 	return &ApplyOptions{ | ||||||
| 		RecordFlags: genericclioptions.NewRecordFlags(), | 		RecordFlags: genericclioptions.NewRecordFlags(), | ||||||
| 		DeleteFlags: NewDeleteFlags("that contains the configuration to apply"), | 		DeleteFlags: NewDeleteFlags("that contains the configuration to apply"), | ||||||
| 		PrintFlags:  printers.NewPrintFlags("created", legacyscheme.Scheme), | 		PrintFlags:  printers.NewPrintFlags("created").WithTypeSetter(scheme.Scheme), | ||||||
|  |  | ||||||
| 		Overwrite:    true, | 		Overwrite:    true, | ||||||
| 		OpenApiPatch: true, | 		OpenApiPatch: true, | ||||||
|   | |||||||
| @@ -26,13 +26,13 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/api/meta" | 	"k8s.io/apimachinery/pkg/api/meta" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl" | 	"k8s.io/kubernetes/pkg/kubectl" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| ) | ) | ||||||
| @@ -83,7 +83,7 @@ var ( | |||||||
|  |  | ||||||
| func NewSetLastAppliedOptions(ioStreams genericclioptions.IOStreams) *SetLastAppliedOptions { | func NewSetLastAppliedOptions(ioStreams genericclioptions.IOStreams) *SetLastAppliedOptions { | ||||||
| 	return &SetLastAppliedOptions{ | 	return &SetLastAppliedOptions{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("configured", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("configured").WithTypeSetter(scheme.Scheme), | ||||||
| 		IOStreams:  ioStreams, | 		IOStreams:  ioStreams, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ go_library( | |||||||
|         "//pkg/kubectl/cmd/util:go_default_library", |         "//pkg/kubectl/cmd/util:go_default_library", | ||||||
|         "//pkg/kubectl/genericclioptions:go_default_library", |         "//pkg/kubectl/genericclioptions:go_default_library", | ||||||
|         "//pkg/kubectl/genericclioptions/resource:go_default_library", |         "//pkg/kubectl/genericclioptions/resource:go_default_library", | ||||||
|  |         "//pkg/kubectl/scheme:go_default_library", | ||||||
|         "//pkg/printers:go_default_library", |         "//pkg/printers:go_default_library", | ||||||
|         "//pkg/registry/rbac/reconciliation:go_default_library", |         "//pkg/registry/rbac/reconciliation:go_default_library", | ||||||
|         "//vendor/github.com/golang/glog:go_default_library", |         "//vendor/github.com/golang/glog:go_default_library", | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ import ( | |||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| 	"k8s.io/kubernetes/pkg/registry/rbac/reconciliation" | 	"k8s.io/kubernetes/pkg/registry/rbac/reconciliation" | ||||||
| ) | ) | ||||||
| @@ -63,7 +64,7 @@ var ( | |||||||
| func NewReconcileOptions(ioStreams genericclioptions.IOStreams) *ReconcileOptions { | func NewReconcileOptions(ioStreams genericclioptions.IOStreams) *ReconcileOptions { | ||||||
| 	return &ReconcileOptions{ | 	return &ReconcileOptions{ | ||||||
| 		FilenameOptions: &resource.FilenameOptions{}, | 		FilenameOptions: &resource.FilenameOptions{}, | ||||||
| 		PrintFlags:      printers.NewPrintFlags("reconciled", legacyscheme.Scheme), | 		PrintFlags:      printers.NewPrintFlags("reconciled").WithTypeSetter(scheme.Scheme), | ||||||
| 		IOStreams:       ioStreams, | 		IOStreams:       ioStreams, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -32,6 +32,7 @@ import ( | |||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| ) | ) | ||||||
| @@ -82,7 +83,7 @@ type AutoscaleOptions struct { | |||||||
|  |  | ||||||
| func NewAutoscaleOptions(ioStreams genericclioptions.IOStreams) *AutoscaleOptions { | func NewAutoscaleOptions(ioStreams genericclioptions.IOStreams) *AutoscaleOptions { | ||||||
| 	return &AutoscaleOptions{ | 	return &AutoscaleOptions{ | ||||||
| 		PrintFlags:      printers.NewPrintFlags("autoscaled", legacyscheme.Scheme), | 		PrintFlags:      printers.NewPrintFlags("autoscaled").WithTypeSetter(scheme.Scheme), | ||||||
| 		FilenameOptions: &resource.FilenameOptions{}, | 		FilenameOptions: &resource.FilenameOptions{}, | ||||||
| 		RecordFlags:     genericclioptions.NewRecordFlags(), | 		RecordFlags:     genericclioptions.NewRecordFlags(), | ||||||
| 		Recorder:        genericclioptions.NoopRecorder{}, | 		Recorder:        genericclioptions.NoopRecorder{}, | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ import ( | |||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
|  |  | ||||||
| @@ -99,7 +100,7 @@ func (o *CertificateOptions) Validate() error { | |||||||
|  |  | ||||||
| func NewCmdCertificateApprove(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { | func NewCmdCertificateApprove(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { | ||||||
| 	options := CertificateOptions{ | 	options := CertificateOptions{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("approved", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("approved").WithTypeSetter(scheme.Scheme), | ||||||
| 		IOStreams:  ioStreams, | 		IOStreams:  ioStreams, | ||||||
| 	} | 	} | ||||||
| 	cmd := &cobra.Command{ | 	cmd := &cobra.Command{ | ||||||
| @@ -156,7 +157,7 @@ func (o *CertificateOptions) RunCertificateApprove(force bool) error { | |||||||
|  |  | ||||||
| func NewCmdCertificateDeny(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { | func NewCmdCertificateDeny(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { | ||||||
| 	options := CertificateOptions{ | 	options := CertificateOptions{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("denied", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("denied").WithTypeSetter(scheme.Scheme), | ||||||
| 		IOStreams:  ioStreams, | 		IOStreams:  ioStreams, | ||||||
| 	} | 	} | ||||||
| 	cmd := &cobra.Command{ | 	cmd := &cobra.Command{ | ||||||
|   | |||||||
| @@ -26,13 +26,13 @@ import ( | |||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | 	api "k8s.io/kubernetes/pkg/apis/core" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers" | 	"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| ) | ) | ||||||
| @@ -57,7 +57,7 @@ type ClusterInfoDumpOptions struct { | |||||||
| // NewCmdCreateSecret groups subcommands to create various types of secrets | // NewCmdCreateSecret groups subcommands to create various types of secrets | ||||||
| func NewCmdClusterInfoDump(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { | func NewCmdClusterInfoDump(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { | ||||||
| 	o := &ClusterInfoDumpOptions{ | 	o := &ClusterInfoDumpOptions{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("").WithTypeSetter(scheme.Scheme), | ||||||
|  |  | ||||||
| 		IOStreams: ioStreams, | 		IOStreams: ioStreams, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -23,7 +23,6 @@ import ( | |||||||
| 	"k8s.io/api/core/v1" | 	"k8s.io/api/core/v1" | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | 	api "k8s.io/kubernetes/pkg/apis/core" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/scheme" | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| @@ -56,21 +55,33 @@ func TestIllegalPackageSourceCheckerThroughPrintFlags(t *testing.T) { | |||||||
| 			obj:                  internalPod(), | 			obj:                  internalPod(), | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			name:                 "json printer: json printer is wrapped in a versioned printer - internal obj should be converted with no error", | 			name:                 "json printer: object containing package path beginning with forbidden prefix is rejected", | ||||||
| 			expectInternalObjErr: false, | 			expectInternalObjErr: true, | ||||||
| 			output:               "json", | 			output:               "json", | ||||||
| 			obj:                  internalPod(), | 			obj:                  internalPod(), | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			name:                 "yaml printer: yaml printer is wrapped in a versioned printer - internal obj should be converted with no error", | 			name:                 "json printer: object containing package path with no forbidden prefix returns no error", | ||||||
| 			expectInternalObjErr: false, | 			expectInternalObjErr: false, | ||||||
|  | 			obj:                  externalPod(), | ||||||
|  | 			output:               "json", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:                 "yaml printer: object containing package path beginning with forbidden prefix is rejected", | ||||||
|  | 			expectInternalObjErr: true, | ||||||
| 			output:               "yaml", | 			output:               "yaml", | ||||||
| 			obj:                  internalPod(), | 			obj:                  internalPod(), | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:                 "yaml printer: object containing package path with no forbidden prefix returns no error", | ||||||
|  | 			expectInternalObjErr: false, | ||||||
|  | 			obj:                  externalPod(), | ||||||
|  | 			output:               "yaml", | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for _, tc := range testCases { | 	for _, tc := range testCases { | ||||||
| 		printFlags := printers.NewPrintFlags("succeeded", legacyscheme.Scheme) | 		printFlags := printers.NewPrintFlags("succeeded").WithTypeSetter(scheme.Scheme) | ||||||
| 		printFlags.OutputFormat = &tc.output | 		printFlags.OutputFormat = &tc.output | ||||||
|  |  | ||||||
| 		printer, err := printFlags.ToPrinter() | 		printer, err := printFlags.ToPrinter() | ||||||
|   | |||||||
| @@ -31,6 +31,8 @@ type kubectlConfigPrintFlags struct { | |||||||
| 	NamePrintFlags     *printers.NamePrintFlags | 	NamePrintFlags     *printers.NamePrintFlags | ||||||
| 	TemplateFlags      *printers.KubeTemplatePrintFlags | 	TemplateFlags      *printers.KubeTemplatePrintFlags | ||||||
|  |  | ||||||
|  | 	TypeSetter *printers.TypeSetterPrinter | ||||||
|  |  | ||||||
| 	OutputFormat *string | 	OutputFormat *string | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -45,15 +47,15 @@ func (f *kubectlConfigPrintFlags) ToPrinter() (printers.ResourcePrinter, error) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) { | 	if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) { | ||||||
| 		return p, err | 		return f.TypeSetter.WrapToPrinter(p, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if p, err := f.NamePrintFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) { | 	if p, err := f.NamePrintFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) { | ||||||
| 		return p, err | 		return f.TypeSetter.WrapToPrinter(p, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if p, err := f.TemplateFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) { | 	if p, err := f.TemplateFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) { | ||||||
| 		return p, err | 		return f.TypeSetter.WrapToPrinter(p, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil, printers.NoCompatiblePrinterError{Options: f} | 	return nil, printers.NoCompatiblePrinterError{Options: f} | ||||||
| @@ -75,14 +77,16 @@ func (f *kubectlConfigPrintFlags) WithDefaultOutput(output string) *kubectlConfi | |||||||
| 	return f | 	return f | ||||||
| } | } | ||||||
|  |  | ||||||
| func newKubeConfigPrintFlags(scheme runtime.ObjectConvertor) *kubectlConfigPrintFlags { | func newKubeConfigPrintFlags(scheme runtime.ObjectTyper) *kubectlConfigPrintFlags { | ||||||
| 	outputFormat := "" | 	outputFormat := "" | ||||||
|  |  | ||||||
| 	return &kubectlConfigPrintFlags{ | 	return &kubectlConfigPrintFlags{ | ||||||
| 		OutputFormat: &outputFormat, | 		OutputFormat: &outputFormat, | ||||||
|  |  | ||||||
| 		JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme), | 		JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(), | ||||||
| 		NamePrintFlags:     printers.NewNamePrintFlags("", scheme), | 		NamePrintFlags:     printers.NewNamePrintFlags(""), | ||||||
| 		TemplateFlags:      printers.NewKubeTemplatePrintFlags(), | 		TemplateFlags:      printers.NewKubeTemplatePrintFlags(), | ||||||
|  |  | ||||||
|  | 		TypeSetter: printers.NewTypeSetter(scheme), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -103,7 +103,7 @@ type ConvertOptions struct { | |||||||
|  |  | ||||||
| func NewConvertOptions(ioStreams genericclioptions.IOStreams) *ConvertOptions { | func NewConvertOptions(ioStreams genericclioptions.IOStreams) *ConvertOptions { | ||||||
| 	return &ConvertOptions{ | 	return &ConvertOptions{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("converted", scheme.Scheme).WithDefaultOutput("yaml"), | 		PrintFlags: printers.NewPrintFlags("converted").WithTypeSetter(scheme.Scheme).WithDefaultOutput("yaml"), | ||||||
| 		local:      true, | 		local:      true, | ||||||
| 		IOStreams:  ioStreams, | 		IOStreams:  ioStreams, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -24,9 +24,9 @@ import ( | |||||||
| 	"runtime" | 	"runtime" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
|  | 	"github.com/golang/glog" | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
| 	"github.com/golang/glog" |  | ||||||
| 	"k8s.io/apimachinery/pkg/api/meta" | 	"k8s.io/apimachinery/pkg/api/meta" | ||||||
| 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | ||||||
| 	kruntime "k8s.io/apimachinery/pkg/runtime" | 	kruntime "k8s.io/apimachinery/pkg/runtime" | ||||||
| @@ -40,6 +40,7 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
|  | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type CreateOptions struct { | type CreateOptions struct { | ||||||
| @@ -350,7 +351,7 @@ type CreateSubcommandOptions struct { | |||||||
| 	Mapper        meta.RESTMapper | 	Mapper        meta.RESTMapper | ||||||
| 	DynamicClient dynamic.Interface | 	DynamicClient dynamic.Interface | ||||||
|  |  | ||||||
| 	PrintObj func(obj kruntime.Object) error | 	PrintObj printers.ResourcePrinterFunc | ||||||
|  |  | ||||||
| 	genericclioptions.IOStreams | 	genericclioptions.IOStreams | ||||||
| } | } | ||||||
| @@ -381,8 +382,8 @@ func (o *CreateSubcommandOptions) Complete(f cmdutil.Factory, cmd *cobra.Command | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	o.PrintObj = func(obj kruntime.Object) error { | 	o.PrintObj = func(obj kruntime.Object, out io.Writer) error { | ||||||
| 		return printer.PrintObj(obj, o.Out) | 		return printer.PrintObj(obj, out) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	o.Namespace, o.EnforceNamespace, err = f.DefaultNamespace() | 	o.Namespace, o.EnforceNamespace, err = f.DefaultNamespace() | ||||||
| @@ -426,6 +427,7 @@ func (o *CreateSubcommandOptions) Run() error { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		asUnstructured := &unstructured.Unstructured{} | 		asUnstructured := &unstructured.Unstructured{} | ||||||
|  |  | ||||||
| 		if err := legacyscheme.Scheme.Convert(obj, asUnstructured, nil); err != nil { | 		if err := legacyscheme.Scheme.Convert(obj, asUnstructured, nil); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| @@ -445,5 +447,5 @@ func (o *CreateSubcommandOptions) Run() error { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return o.PrintObj(obj) | 	return o.PrintObj(obj, o.Out) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ import ( | |||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
| 	rbacv1 "k8s.io/api/rbac/v1" | 	rbacv1 "k8s.io/api/rbac/v1" | ||||||
|  | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| @@ -156,7 +157,10 @@ func (c *CreateClusterRoleOptions) Validate() error { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (c *CreateClusterRoleOptions) RunCreateRole() error { | func (c *CreateClusterRoleOptions) RunCreateRole() error { | ||||||
| 	clusterRole := &rbacv1.ClusterRole{} | 	clusterRole := &rbacv1.ClusterRole{ | ||||||
|  | 		// this is ok because we know exactly how we want to be serialized | ||||||
|  | 		TypeMeta: metav1.TypeMeta{APIVersion: rbacv1.SchemeGroupVersion.String(), Kind: "ClusterRole"}, | ||||||
|  | 	} | ||||||
| 	clusterRole.Name = c.Name | 	clusterRole.Name = c.Name | ||||||
| 	rules, err := generateResourcePolicyRules(c.Mapper, c.Verbs, c.Resources, c.ResourceNames, c.NonResourceURLs) | 	rules, err := generateResourcePolicyRules(c.Mapper, c.Verbs, c.Resources, c.ResourceNames, c.NonResourceURLs) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ import ( | |||||||
|  |  | ||||||
| 	rbacv1 "k8s.io/api/rbac/v1" | 	rbacv1 "k8s.io/api/rbac/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/api/meta" | 	"k8s.io/apimachinery/pkg/api/meta" | ||||||
|  | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||||
| 	"k8s.io/apimachinery/pkg/util/sets" | 	"k8s.io/apimachinery/pkg/util/sets" | ||||||
| @@ -299,7 +300,10 @@ func (o *CreateRoleOptions) validateResource() error { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (o *CreateRoleOptions) RunCreateRole() error { | func (o *CreateRoleOptions) RunCreateRole() error { | ||||||
| 	role := &rbacv1.Role{} | 	role := &rbacv1.Role{ | ||||||
|  | 		// this is ok because we know exactly how we want to be serialized | ||||||
|  | 		TypeMeta: metav1.TypeMeta{APIVersion: rbacv1.SchemeGroupVersion.String(), Kind: "Role"}, | ||||||
|  | 	} | ||||||
| 	role.Name = o.Name | 	role.Name = o.Name | ||||||
| 	rules, err := generateResourcePolicyRules(o.Mapper, o.Verbs, o.Resources, o.ResourceNames, []string{}) | 	rules, err := generateResourcePolicyRules(o.Mapper, o.Verbs, o.Resources, o.ResourceNames, []string{}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
| @@ -31,6 +31,8 @@ type PrintFlags struct { | |||||||
| 	NamePrintFlags     *printers.NamePrintFlags | 	NamePrintFlags     *printers.NamePrintFlags | ||||||
| 	TemplateFlags      *printers.KubeTemplatePrintFlags | 	TemplateFlags      *printers.KubeTemplatePrintFlags | ||||||
|  |  | ||||||
|  | 	TypeSetter *printers.TypeSetterPrinter | ||||||
|  |  | ||||||
| 	OutputFormat *string | 	OutputFormat *string | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -45,15 +47,15 @@ func (f *PrintFlags) ToPrinter() (printers.ResourcePrinter, error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) { | 	if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) { | ||||||
| 		return p, err | 		return f.TypeSetter.WrapToPrinter(p, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if p, err := f.NamePrintFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) { | 	if p, err := f.NamePrintFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) { | ||||||
| 		return p, err | 		return f.TypeSetter.WrapToPrinter(p, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if p, err := f.TemplateFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) { | 	if p, err := f.TemplateFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) { | ||||||
| 		return p, err | 		return f.TypeSetter.WrapToPrinter(p, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil, printers.NoCompatiblePrinterError{Options: f} | 	return nil, printers.NoCompatiblePrinterError{Options: f} | ||||||
| @@ -69,14 +71,16 @@ func (f *PrintFlags) AddFlags(cmd *cobra.Command) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewPrintFlags(operation string, scheme runtime.ObjectConvertor) *PrintFlags { | func NewPrintFlags(operation string, scheme runtime.ObjectTyper) *PrintFlags { | ||||||
| 	outputFormat := "" | 	outputFormat := "" | ||||||
|  |  | ||||||
| 	return &PrintFlags{ | 	return &PrintFlags{ | ||||||
| 		OutputFormat: &outputFormat, | 		OutputFormat: &outputFormat, | ||||||
|  |  | ||||||
| 		JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme), | 		JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(), | ||||||
| 		NamePrintFlags:     printers.NewNamePrintFlags(operation, scheme), | 		NamePrintFlags:     printers.NewNamePrintFlags(operation), | ||||||
| 		TemplateFlags:      printers.NewKubeTemplatePrintFlags(), | 		TemplateFlags:      printers.NewKubeTemplatePrintFlags(), | ||||||
|  |  | ||||||
|  | 		TypeSetter: printers.NewTypeSetter(scheme), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -41,6 +41,7 @@ import ( | |||||||
| 	"k8s.io/client-go/kubernetes" | 	"k8s.io/client-go/kubernetes" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" | 	"k8s.io/kubernetes/pkg/api/legacyscheme" | ||||||
| @@ -107,7 +108,7 @@ var ( | |||||||
|  |  | ||||||
| func NewCmdCordon(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { | func NewCmdCordon(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { | ||||||
| 	options := &DrainOptions{ | 	options := &DrainOptions{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("cordoned", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("cordoned").WithTypeSetter(scheme.Scheme), | ||||||
|  |  | ||||||
| 		IOStreams: ioStreams, | 		IOStreams: ioStreams, | ||||||
| 	} | 	} | ||||||
| @@ -139,7 +140,7 @@ var ( | |||||||
|  |  | ||||||
| func NewCmdUncordon(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { | func NewCmdUncordon(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { | ||||||
| 	options := &DrainOptions{ | 	options := &DrainOptions{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("uncordoned", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("uncordoned").WithTypeSetter(scheme.Scheme), | ||||||
| 		IOStreams:  ioStreams, | 		IOStreams:  ioStreams, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -195,7 +196,7 @@ var ( | |||||||
|  |  | ||||||
| func NewDrainOptions(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *DrainOptions { | func NewDrainOptions(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *DrainOptions { | ||||||
| 	return &DrainOptions{ | 	return &DrainOptions{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("drained", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("drained").WithTypeSetter(scheme.Scheme), | ||||||
|  |  | ||||||
| 		IOStreams:          ioStreams, | 		IOStreams:          ioStreams, | ||||||
| 		backOff:            clockwork.NewRealClock(), | 		backOff:            clockwork.NewRealClock(), | ||||||
|   | |||||||
| @@ -834,7 +834,7 @@ func TestDeletePods(t *testing.T) { | |||||||
| 			defer tf.Cleanup() | 			defer tf.Cleanup() | ||||||
|  |  | ||||||
| 			o := DrainOptions{ | 			o := DrainOptions{ | ||||||
| 				PrintFlags: printers.NewPrintFlags("drained", legacyscheme.Scheme), | 				PrintFlags: printers.NewPrintFlags("drained").WithTypeSetter(scheme.Scheme), | ||||||
| 			} | 			} | ||||||
| 			o.Out = os.Stdout | 			o.Out = os.Stdout | ||||||
|  |  | ||||||
|   | |||||||
| @@ -36,6 +36,7 @@ import ( | |||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| ) | ) | ||||||
| @@ -110,7 +111,7 @@ type ExposeServiceOptions struct { | |||||||
| func NewExposeServiceOptions(ioStreams genericclioptions.IOStreams) *ExposeServiceOptions { | func NewExposeServiceOptions(ioStreams genericclioptions.IOStreams) *ExposeServiceOptions { | ||||||
| 	return &ExposeServiceOptions{ | 	return &ExposeServiceOptions{ | ||||||
| 		RecordFlags: genericclioptions.NewRecordFlags(), | 		RecordFlags: genericclioptions.NewRecordFlags(), | ||||||
| 		PrintFlags:  printers.NewPrintFlags("exposed", legacyscheme.Scheme), | 		PrintFlags:  printers.NewPrintFlags("exposed").WithTypeSetter(scheme.Scheme), | ||||||
|  |  | ||||||
| 		Recorder:  genericclioptions.NoopRecorder{}, | 		Recorder:  genericclioptions.NoopRecorder{}, | ||||||
| 		IOStreams: ioStreams, | 		IOStreams: ioStreams, | ||||||
|   | |||||||
| @@ -21,7 +21,6 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	"github.com/golang/glog" | 	"github.com/golang/glog" | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
| @@ -42,7 +41,6 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/kubectl" | 	"k8s.io/kubernetes/pkg/kubectl" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
| @@ -420,6 +418,13 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e | |||||||
| 			lastMapping = mapping | 			lastMapping = mapping | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		// ensure a versioned object is passed to the custom-columns printer | ||||||
|  | 		// if we are using OpenAPI columns to print | ||||||
|  | 		if o.PrintWithOpenAPICols { | ||||||
|  | 			printer.PrintObj(info.Object, w) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		internalObj, err := legacyscheme.Scheme.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()) | 		internalObj, err := legacyscheme.Scheme.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			// if there's an error, try to print what you have (mirrors old behavior). | 			// if there's an error, try to print what you have (mirrors old behavior). | ||||||
| @@ -733,47 +738,3 @@ func shouldGetNewPrinterForMapping(printer printers.ResourcePrinter, lastMapping | |||||||
| func cmdSpecifiesOutputFmt(cmd *cobra.Command) bool { | func cmdSpecifiesOutputFmt(cmd *cobra.Command) bool { | ||||||
| 	return cmdutil.GetFlagString(cmd, "output") != "" | 	return cmdutil.GetFlagString(cmd, "output") != "" | ||||||
| } | } | ||||||
|  |  | ||||||
| // outputOptsForMappingFromOpenAPI looks for the output format metatadata in the |  | ||||||
| // openapi schema and modifies the passed print options for the mapping if found. |  | ||||||
| func updatePrintOptionsForOpenAPI(f cmdutil.Factory, mapping *meta.RESTMapping, printOpts *printers.PrintOptions) bool { |  | ||||||
|  |  | ||||||
| 	// user has not specified any output format, check if OpenAPI has |  | ||||||
| 	// default specification to print this resource type |  | ||||||
| 	api, err := f.OpenAPISchema() |  | ||||||
| 	if err != nil { |  | ||||||
| 		// Error getting schema |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	// Found openapi metadata for this resource |  | ||||||
| 	schema := api.LookupResource(mapping.GroupVersionKind) |  | ||||||
| 	if schema == nil { |  | ||||||
| 		// Schema not found, return empty columns |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	columns, found := openapi.GetPrintColumns(schema.GetExtensions()) |  | ||||||
| 	if !found { |  | ||||||
| 		// Extension not found, return empty columns |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return outputOptsFromStr(columns, printOpts) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // outputOptsFromStr parses the print-column metadata and generates printer.OutputOptions object. |  | ||||||
| func outputOptsFromStr(columnStr string, printOpts *printers.PrintOptions) bool { |  | ||||||
| 	if columnStr == "" { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	parts := strings.SplitN(columnStr, "=", 2) |  | ||||||
| 	if len(parts) < 2 { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	printOpts.OutputFormatType = parts[0] |  | ||||||
| 	printOpts.OutputFormatArgument = parts[1] |  | ||||||
| 	printOpts.AllowMissingKeys = true |  | ||||||
|  |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -161,8 +161,8 @@ func NewGetPrintFlags(scheme runtime.ObjectConvertor) *PrintFlags { | |||||||
| 		OutputFormat: &outputFormat, | 		OutputFormat: &outputFormat, | ||||||
| 		NoHeaders:    &noHeaders, | 		NoHeaders:    &noHeaders, | ||||||
|  |  | ||||||
| 		JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme), | 		JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(), | ||||||
| 		NamePrintFlags:     printers.NewNamePrintFlags("", scheme), | 		NamePrintFlags:     printers.NewNamePrintFlags(""), | ||||||
| 		TemplateFlags:      printers.NewKubeTemplatePrintFlags(), | 		TemplateFlags:      printers.NewKubeTemplatePrintFlags(), | ||||||
| 		HumanReadableFlags: NewHumanPrintFlags(), | 		HumanReadableFlags: NewHumanPrintFlags(), | ||||||
| 		CustomColumnsFlags: printers.NewCustomColumnsPrintFlags(), | 		CustomColumnsFlags: printers.NewCustomColumnsPrintFlags(), | ||||||
|   | |||||||
| @@ -32,13 +32,13 @@ import ( | |||||||
| 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||||||
| 	"k8s.io/apimachinery/pkg/util/json" | 	"k8s.io/apimachinery/pkg/util/json" | ||||||
| 	"k8s.io/apimachinery/pkg/util/validation" | 	"k8s.io/apimachinery/pkg/util/validation" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme" | 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| ) | ) | ||||||
| @@ -115,7 +115,7 @@ func NewLabelOptions(ioStreams genericclioptions.IOStreams) *LabelOptions { | |||||||
| 		RecordFlags: genericclioptions.NewRecordFlags(), | 		RecordFlags: genericclioptions.NewRecordFlags(), | ||||||
| 		Recorder:    genericclioptions.NoopRecorder{}, | 		Recorder:    genericclioptions.NoopRecorder{}, | ||||||
|  |  | ||||||
| 		PrintFlags: printers.NewPrintFlags("labeled", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("labeled").WithTypeSetter(scheme.Scheme), | ||||||
|  |  | ||||||
| 		IOStreams: ioStreams, | 		IOStreams: ioStreams, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -33,7 +33,6 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/util/sets" | 	"k8s.io/apimachinery/pkg/util/sets" | ||||||
| 	"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/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| @@ -99,7 +98,7 @@ func NewPatchOptions(ioStreams genericclioptions.IOStreams) *PatchOptions { | |||||||
| 	return &PatchOptions{ | 	return &PatchOptions{ | ||||||
| 		RecordFlags: genericclioptions.NewRecordFlags(), | 		RecordFlags: genericclioptions.NewRecordFlags(), | ||||||
| 		Recorder:    genericclioptions.NoopRecorder{}, | 		Recorder:    genericclioptions.NoopRecorder{}, | ||||||
| 		PrintFlags:  printers.NewPrintFlags("patched", legacyscheme.Scheme), | 		PrintFlags:  printers.NewPrintFlags("patched").WithTypeSetter(scheme.Scheme), | ||||||
| 		IOStreams:   ioStreams, | 		IOStreams:   ioStreams, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -29,7 +29,6 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/api/errors" | 	"k8s.io/apimachinery/pkg/api/errors" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl" | 	"k8s.io/kubernetes/pkg/kubectl" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| @@ -97,7 +96,7 @@ func NewReplaceOptions(streams genericclioptions.IOStreams) *ReplaceOptions { | |||||||
| 		// we only support "-o name" for this command, so only register the name printer | 		// we only support "-o name" for this command, so only register the name printer | ||||||
| 		PrintFlags: &printers.PrintFlags{ | 		PrintFlags: &printers.PrintFlags{ | ||||||
| 			OutputFormat:   &outputFormat, | 			OutputFormat:   &outputFormat, | ||||||
| 			NamePrintFlags: printers.NewNamePrintFlags("replaced", legacyscheme.Scheme), | 			NamePrintFlags: printers.NewNamePrintFlags("replaced"), | ||||||
| 		}, | 		}, | ||||||
| 		DeleteFlags: NewDeleteFlags("to use to replace the resource."), | 		DeleteFlags: NewDeleteFlags("to use to replace the resource."), | ||||||
|  |  | ||||||
|   | |||||||
| @@ -38,6 +38,7 @@ import ( | |||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util" | 	"k8s.io/kubernetes/pkg/kubectl/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/validation" | 	"k8s.io/kubernetes/pkg/kubectl/validation" | ||||||
| @@ -114,7 +115,7 @@ type RollingUpdateOptions struct { | |||||||
|  |  | ||||||
| func NewRollingUpdateOptions(streams genericclioptions.IOStreams) *RollingUpdateOptions { | func NewRollingUpdateOptions(streams genericclioptions.IOStreams) *RollingUpdateOptions { | ||||||
| 	return &RollingUpdateOptions{ | 	return &RollingUpdateOptions{ | ||||||
| 		PrintFlags:      printers.NewPrintFlags("rolling updated", legacyscheme.Scheme), | 		PrintFlags:      printers.NewPrintFlags("rolling updated").WithTypeSetter(scheme.Scheme), | ||||||
| 		FilenameOptions: &resource.FilenameOptions{}, | 		FilenameOptions: &resource.FilenameOptions{}, | ||||||
| 		DeploymentKey:   "deployment", | 		DeploymentKey:   "deployment", | ||||||
| 		Timeout:         timeout, | 		Timeout:         timeout, | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ go_library( | |||||||
|         "//pkg/kubectl/cmd/util:go_default_library", |         "//pkg/kubectl/cmd/util:go_default_library", | ||||||
|         "//pkg/kubectl/genericclioptions:go_default_library", |         "//pkg/kubectl/genericclioptions:go_default_library", | ||||||
|         "//pkg/kubectl/genericclioptions/resource:go_default_library", |         "//pkg/kubectl/genericclioptions/resource:go_default_library", | ||||||
|  |         "//pkg/kubectl/scheme:go_default_library", | ||||||
|         "//pkg/kubectl/util/i18n:go_default_library", |         "//pkg/kubectl/util/i18n:go_default_library", | ||||||
|         "//pkg/printers:go_default_library", |         "//pkg/printers:go_default_library", | ||||||
|         "//pkg/util/interrupt:go_default_library", |         "//pkg/util/interrupt:go_default_library", | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ import ( | |||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| ) | ) | ||||||
| @@ -63,7 +64,7 @@ var ( | |||||||
|  |  | ||||||
| func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { | func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { | ||||||
| 	o := &PauseConfig{ | 	o := &PauseConfig{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("paused", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("paused").WithTypeSetter(scheme.Scheme), | ||||||
| 		IOStreams:  streams, | 		IOStreams:  streams, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ import ( | |||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| ) | ) | ||||||
| @@ -61,7 +62,7 @@ var ( | |||||||
|  |  | ||||||
| func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { | func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { | ||||||
| 	o := &ResumeConfig{ | 	o := &ResumeConfig{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("resumed", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("resumed").WithTypeSetter(scheme.Scheme), | ||||||
| 		IOStreams:  streams, | 		IOStreams:  streams, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| ) | ) | ||||||
| @@ -64,7 +65,7 @@ var ( | |||||||
|  |  | ||||||
| func NewCmdRolloutUndo(f cmdutil.Factory, out io.Writer) *cobra.Command { | func NewCmdRolloutUndo(f cmdutil.Factory, out io.Writer) *cobra.Command { | ||||||
| 	o := &UndoOptions{ | 	o := &UndoOptions{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("").WithTypeSetter(scheme.Scheme), | ||||||
| 		ToRevision: int64(0), | 		ToRevision: int64(0), | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -127,7 +127,7 @@ type RunOptions struct { | |||||||
|  |  | ||||||
| func NewRunOptions(streams genericclioptions.IOStreams) *RunOptions { | func NewRunOptions(streams genericclioptions.IOStreams) *RunOptions { | ||||||
| 	return &RunOptions{ | 	return &RunOptions{ | ||||||
| 		PrintFlags:  printers.NewPrintFlags("created", legacyscheme.Scheme), | 		PrintFlags:  printers.NewPrintFlags("created").WithTypeSetter(scheme.Scheme), | ||||||
| 		DeleteFlags: NewDeleteFlags("to use to replace the resource."), | 		DeleteFlags: NewDeleteFlags("to use to replace the resource."), | ||||||
| 		RecordFlags: genericclioptions.NewRecordFlags(), | 		RecordFlags: genericclioptions.NewRecordFlags(), | ||||||
|  |  | ||||||
|   | |||||||
| @@ -198,7 +198,7 @@ func TestRunArgsFollowDashRules(t *testing.T) { | |||||||
| 			cmd.Flags().Set("image", "nginx") | 			cmd.Flags().Set("image", "nginx") | ||||||
| 			cmd.Flags().Set("generator", "run/v1") | 			cmd.Flags().Set("generator", "run/v1") | ||||||
|  |  | ||||||
| 			printFlags := printers.NewPrintFlags("created", legacyscheme.Scheme) | 			printFlags := printers.NewPrintFlags("created").WithTypeSetter(scheme.Scheme) | ||||||
| 			printer, err := printFlags.ToPrinter() | 			printer, err := printFlags.ToPrinter() | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				t.Errorf("unexpected error: %v", err) | 				t.Errorf("unexpected error: %v", err) | ||||||
| @@ -366,7 +366,7 @@ func TestGenerateService(t *testing.T) { | |||||||
| 				}), | 				}), | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			printFlags := printers.NewPrintFlags("created", legacyscheme.Scheme) | 			printFlags := printers.NewPrintFlags("created").WithTypeSetter(scheme.Scheme) | ||||||
| 			printer, err := printFlags.ToPrinter() | 			printer, err := printFlags.ToPrinter() | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				t.Errorf("unexpected error: %v", err) | 				t.Errorf("unexpected error: %v", err) | ||||||
|   | |||||||
| @@ -26,7 +26,6 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/api/meta" | 	"k8s.io/apimachinery/pkg/api/meta" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||||
| 	batchclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/internalversion" | 	batchclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/internalversion" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl" | 	"k8s.io/kubernetes/pkg/kubectl" | ||||||
| @@ -101,7 +100,7 @@ func NewScaleOptions(ioStreams genericclioptions.IOStreams) *ScaleOptions { | |||||||
| 		// we only support "-o name" for this command, so only register the name printer | 		// we only support "-o name" for this command, so only register the name printer | ||||||
| 		PrintFlags: &printers.PrintFlags{ | 		PrintFlags: &printers.PrintFlags{ | ||||||
| 			OutputFormat:   &outputFormat, | 			OutputFormat:   &outputFormat, | ||||||
| 			NamePrintFlags: printers.NewNamePrintFlags("scaled", legacyscheme.Scheme), | 			NamePrintFlags: printers.NewNamePrintFlags("scaled"), | ||||||
| 		}, | 		}, | ||||||
| 		RecordFlags:     genericclioptions.NewRecordFlags(), | 		RecordFlags:     genericclioptions.NewRecordFlags(), | ||||||
| 		CurrentReplicas: -1, | 		CurrentReplicas: -1, | ||||||
|   | |||||||
| @@ -19,7 +19,6 @@ go_library( | |||||||
|     importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/set", |     importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/set", | ||||||
|     visibility = ["//build/visible_to:pkg_kubectl_cmd_set_CONSUMERS"], |     visibility = ["//build/visible_to:pkg_kubectl_cmd_set_CONSUMERS"], | ||||||
|     deps = [ |     deps = [ | ||||||
|         "//pkg/api/legacyscheme:go_default_library", |  | ||||||
|         "//pkg/apis/rbac:go_default_library", |         "//pkg/apis/rbac:go_default_library", | ||||||
|         "//pkg/kubectl:go_default_library", |         "//pkg/kubectl:go_default_library", | ||||||
|         "//pkg/kubectl/cmd/templates:go_default_library", |         "//pkg/kubectl/cmd/templates:go_default_library", | ||||||
|   | |||||||
| @@ -30,7 +30,6 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||||||
| 	"k8s.io/client-go/kubernetes" | 	"k8s.io/client-go/kubernetes" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	envutil "k8s.io/kubernetes/pkg/kubectl/cmd/util/env" | 	envutil "k8s.io/kubernetes/pkg/kubectl/cmd/util/env" | ||||||
| @@ -127,7 +126,7 @@ type EnvOptions struct { | |||||||
| // pod templates are selected by default and allowing environment to be overwritten | // pod templates are selected by default and allowing environment to be overwritten | ||||||
| func NewEnvOptions(streams genericclioptions.IOStreams) *EnvOptions { | func NewEnvOptions(streams genericclioptions.IOStreams) *EnvOptions { | ||||||
| 	return &EnvOptions{ | 	return &EnvOptions{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("env updated", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("env updated").WithTypeSetter(scheme.Scheme), | ||||||
|  |  | ||||||
| 		ContainerSelector: "*", | 		ContainerSelector: "*", | ||||||
| 		Overwrite:         true, | 		Overwrite:         true, | ||||||
|   | |||||||
| @@ -63,11 +63,7 @@ func TestSetEnvLocal(t *testing.T) { | |||||||
|  |  | ||||||
| 	streams, _, buf, bufErr := genericclioptions.NewTestIOStreams() | 	streams, _, buf, bufErr := genericclioptions.NewTestIOStreams() | ||||||
| 	opts := NewEnvOptions(streams) | 	opts := NewEnvOptions(streams) | ||||||
| 	opts.PrintFlags = &printers.PrintFlags{ | 	opts.PrintFlags = printers.NewPrintFlags("").WithDefaultOutput(outputFormat).WithTypeSetter(scheme.Scheme) | ||||||
| 		JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 		NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
| 		OutputFormat:       &outputFormat, |  | ||||||
| 	} |  | ||||||
| 	opts.FilenameOptions = resource.FilenameOptions{ | 	opts.FilenameOptions = resource.FilenameOptions{ | ||||||
| 		Filenames: []string{"../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}, | 		Filenames: []string{"../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}, | ||||||
| 	} | 	} | ||||||
| @@ -105,11 +101,7 @@ func TestSetMultiResourcesEnvLocal(t *testing.T) { | |||||||
| 	outputFormat := "name" | 	outputFormat := "name" | ||||||
| 	streams, _, buf, bufErr := genericclioptions.NewTestIOStreams() | 	streams, _, buf, bufErr := genericclioptions.NewTestIOStreams() | ||||||
| 	opts := NewEnvOptions(streams) | 	opts := NewEnvOptions(streams) | ||||||
| 	opts.PrintFlags = &printers.PrintFlags{ | 	opts.PrintFlags = printers.NewPrintFlags("").WithDefaultOutput(outputFormat).WithTypeSetter(scheme.Scheme) | ||||||
| 		JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 		NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
| 		OutputFormat:       &outputFormat, |  | ||||||
| 	} |  | ||||||
| 	opts.FilenameOptions = resource.FilenameOptions{ | 	opts.FilenameOptions = resource.FilenameOptions{ | ||||||
| 		Filenames: []string{"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"}, | 		Filenames: []string{"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"}, | ||||||
| 	} | 	} | ||||||
| @@ -491,11 +483,7 @@ func TestSetEnvRemote(t *testing.T) { | |||||||
| 			outputFormat := "yaml" | 			outputFormat := "yaml" | ||||||
| 			streams := genericclioptions.NewTestIOStreamsDiscard() | 			streams := genericclioptions.NewTestIOStreamsDiscard() | ||||||
| 			opts := NewEnvOptions(streams) | 			opts := NewEnvOptions(streams) | ||||||
| 			opts.PrintFlags = &printers.PrintFlags{ | 			opts.PrintFlags = printers.NewPrintFlags("").WithDefaultOutput(outputFormat).WithTypeSetter(scheme.Scheme) | ||||||
| 				JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 				NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
| 				OutputFormat:       &outputFormat, |  | ||||||
| 			} |  | ||||||
| 			opts.Local = false | 			opts.Local = false | ||||||
| 			opts.IOStreams = streams | 			opts.IOStreams = streams | ||||||
| 			err := opts.Complete(tf, NewCmdEnv(tf, streams), input.args) | 			err := opts.Complete(tf, NewCmdEnv(tf, streams), input.args) | ||||||
|   | |||||||
| @@ -26,7 +26,6 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| @@ -88,7 +87,7 @@ var ( | |||||||
|  |  | ||||||
| func NewImageOptions(streams genericclioptions.IOStreams) *SetImageOptions { | func NewImageOptions(streams genericclioptions.IOStreams) *SetImageOptions { | ||||||
| 	return &SetImageOptions{ | 	return &SetImageOptions{ | ||||||
| 		PrintFlags:  printers.NewPrintFlags("image updated", legacyscheme.Scheme), | 		PrintFlags:  printers.NewPrintFlags("image updated").WithTypeSetter(scheme.Scheme), | ||||||
| 		RecordFlags: genericclioptions.NewRecordFlags(), | 		RecordFlags: genericclioptions.NewRecordFlags(), | ||||||
|  |  | ||||||
| 		Recorder: genericclioptions.NoopRecorder{}, | 		Recorder: genericclioptions.NoopRecorder{}, | ||||||
|   | |||||||
| @@ -70,12 +70,7 @@ func TestImageLocal(t *testing.T) { | |||||||
| 	cmd.Flags().Set("local", "true") | 	cmd.Flags().Set("local", "true") | ||||||
|  |  | ||||||
| 	opts := SetImageOptions{ | 	opts := SetImageOptions{ | ||||||
| 		PrintFlags: &printers.PrintFlags{ | 		PrintFlags: printers.NewPrintFlags("").WithDefaultOutput(outputFormat).WithTypeSetter(scheme.Scheme), | ||||||
| 			JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 			NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
|  |  | ||||||
| 			OutputFormat: &outputFormat, |  | ||||||
| 		}, |  | ||||||
| 		FilenameOptions: resource.FilenameOptions{ | 		FilenameOptions: resource.FilenameOptions{ | ||||||
| 			Filenames: []string{"../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}}, | 			Filenames: []string{"../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}}, | ||||||
| 		Local:     true, | 		Local:     true, | ||||||
| @@ -97,10 +92,7 @@ func TestImageLocal(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestSetImageValidation(t *testing.T) { | func TestSetImageValidation(t *testing.T) { | ||||||
| 	printFlags := &printers.PrintFlags{ | 	printFlags := printers.NewPrintFlags("").WithTypeSetter(scheme.Scheme) | ||||||
| 		JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 		NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	testCases := []struct { | 	testCases := []struct { | ||||||
| 		name         string | 		name         string | ||||||
| @@ -191,12 +183,7 @@ func TestSetMultiResourcesImageLocal(t *testing.T) { | |||||||
| 	cmd.Flags().Set("local", "true") | 	cmd.Flags().Set("local", "true") | ||||||
|  |  | ||||||
| 	opts := SetImageOptions{ | 	opts := SetImageOptions{ | ||||||
| 		PrintFlags: &printers.PrintFlags{ | 		PrintFlags: printers.NewPrintFlags("").WithDefaultOutput(outputFormat).WithTypeSetter(scheme.Scheme), | ||||||
| 			JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 			NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
|  |  | ||||||
| 			OutputFormat: &outputFormat, |  | ||||||
| 		}, |  | ||||||
| 		FilenameOptions: resource.FilenameOptions{ | 		FilenameOptions: resource.FilenameOptions{ | ||||||
| 			Filenames: []string{"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"}}, | 			Filenames: []string{"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"}}, | ||||||
| 		Local:     true, | 		Local:     true, | ||||||
| @@ -583,12 +570,7 @@ func TestSetImageRemote(t *testing.T) { | |||||||
| 			cmd := NewCmdImage(tf, streams) | 			cmd := NewCmdImage(tf, streams) | ||||||
| 			cmd.Flags().Set("output", outputFormat) | 			cmd.Flags().Set("output", outputFormat) | ||||||
| 			opts := SetImageOptions{ | 			opts := SetImageOptions{ | ||||||
| 				PrintFlags: &printers.PrintFlags{ | 				PrintFlags: printers.NewPrintFlags("").WithDefaultOutput(outputFormat).WithTypeSetter(scheme.Scheme), | ||||||
| 					JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 					NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
|  |  | ||||||
| 					OutputFormat: &outputFormat, |  | ||||||
| 				}, |  | ||||||
|  |  | ||||||
| 				Local:     false, | 				Local:     false, | ||||||
| 				IOStreams: streams, | 				IOStreams: streams, | ||||||
|   | |||||||
| @@ -29,7 +29,6 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl" | 	"k8s.io/kubernetes/pkg/kubectl" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| @@ -95,7 +94,7 @@ type SetResourcesOptions struct { | |||||||
| // pod templates are selected by default. | // pod templates are selected by default. | ||||||
| func NewResourcesOptions(streams genericclioptions.IOStreams) *SetResourcesOptions { | func NewResourcesOptions(streams genericclioptions.IOStreams) *SetResourcesOptions { | ||||||
| 	return &SetResourcesOptions{ | 	return &SetResourcesOptions{ | ||||||
| 		PrintFlags:  printers.NewPrintFlags("resource requirements updated", legacyscheme.Scheme), | 		PrintFlags:  printers.NewPrintFlags("resource requirements updated").WithTypeSetter(scheme.Scheme), | ||||||
| 		RecordFlags: genericclioptions.NewRecordFlags(), | 		RecordFlags: genericclioptions.NewRecordFlags(), | ||||||
|  |  | ||||||
| 		Recorder: genericclioptions.NoopRecorder{}, | 		Recorder: genericclioptions.NoopRecorder{}, | ||||||
|   | |||||||
| @@ -70,12 +70,7 @@ func TestResourcesLocal(t *testing.T) { | |||||||
| 	cmd.Flags().Set("local", "true") | 	cmd.Flags().Set("local", "true") | ||||||
|  |  | ||||||
| 	opts := SetResourcesOptions{ | 	opts := SetResourcesOptions{ | ||||||
| 		PrintFlags: &printers.PrintFlags{ | 		PrintFlags: printers.NewPrintFlags("").WithDefaultOutput(outputFormat).WithTypeSetter(scheme.Scheme), | ||||||
| 			JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 			NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
|  |  | ||||||
| 			OutputFormat: &outputFormat, |  | ||||||
| 		}, |  | ||||||
| 		FilenameOptions: resource.FilenameOptions{ | 		FilenameOptions: resource.FilenameOptions{ | ||||||
| 			Filenames: []string{"../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}}, | 			Filenames: []string{"../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}}, | ||||||
| 		Local:             true, | 		Local:             true, | ||||||
| @@ -124,12 +119,7 @@ func TestSetMultiResourcesLimitsLocal(t *testing.T) { | |||||||
| 	cmd.Flags().Set("local", "true") | 	cmd.Flags().Set("local", "true") | ||||||
|  |  | ||||||
| 	opts := SetResourcesOptions{ | 	opts := SetResourcesOptions{ | ||||||
| 		PrintFlags: &printers.PrintFlags{ | 		PrintFlags: printers.NewPrintFlags("").WithDefaultOutput(outputFormat).WithTypeSetter(scheme.Scheme), | ||||||
| 			JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 			NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
|  |  | ||||||
| 			OutputFormat: &outputFormat, |  | ||||||
| 		}, |  | ||||||
| 		FilenameOptions: resource.FilenameOptions{ | 		FilenameOptions: resource.FilenameOptions{ | ||||||
| 			Filenames: []string{"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"}}, | 			Filenames: []string{"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"}}, | ||||||
| 		Local:             true, | 		Local:             true, | ||||||
| @@ -504,12 +494,7 @@ func TestSetResourcesRemote(t *testing.T) { | |||||||
| 			cmd := NewCmdResources(tf, streams) | 			cmd := NewCmdResources(tf, streams) | ||||||
| 			cmd.Flags().Set("output", outputFormat) | 			cmd.Flags().Set("output", outputFormat) | ||||||
| 			opts := SetResourcesOptions{ | 			opts := SetResourcesOptions{ | ||||||
| 				PrintFlags: &printers.PrintFlags{ | 				PrintFlags: printers.NewPrintFlags("").WithDefaultOutput(outputFormat).WithTypeSetter(scheme.Scheme), | ||||||
| 					JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 					NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
|  |  | ||||||
| 					OutputFormat: &outputFormat, |  | ||||||
| 				}, |  | ||||||
|  |  | ||||||
| 				Limits:            "cpu=200m,memory=512Mi", | 				Limits:            "cpu=200m,memory=512Mi", | ||||||
| 				ContainerSelector: "*", | 				ContainerSelector: "*", | ||||||
|   | |||||||
| @@ -29,7 +29,6 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	"k8s.io/apimachinery/pkg/util/validation" | 	"k8s.io/apimachinery/pkg/util/validation" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| @@ -80,7 +79,7 @@ var ( | |||||||
|  |  | ||||||
| func NewSelectorOptions(streams genericclioptions.IOStreams) *SetSelectorOptions { | func NewSelectorOptions(streams genericclioptions.IOStreams) *SetSelectorOptions { | ||||||
| 	return &SetSelectorOptions{ | 	return &SetSelectorOptions{ | ||||||
| 		PrintFlags:  printers.NewPrintFlags("selector updated", legacyscheme.Scheme), | 		PrintFlags:  printers.NewPrintFlags("selector updated").WithTypeSetter(scheme.Scheme), | ||||||
| 		RecordFlags: genericclioptions.NewRecordFlags(), | 		RecordFlags: genericclioptions.NewRecordFlags(), | ||||||
|  |  | ||||||
| 		Recorder: genericclioptions.NoopRecorder{}, | 		Recorder: genericclioptions.NoopRecorder{}, | ||||||
|   | |||||||
| @@ -29,7 +29,6 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| @@ -80,7 +79,7 @@ type SetServiceAccountOptions struct { | |||||||
|  |  | ||||||
| func NewSetServiceAccountOptions(streams genericclioptions.IOStreams) *SetServiceAccountOptions { | func NewSetServiceAccountOptions(streams genericclioptions.IOStreams) *SetServiceAccountOptions { | ||||||
| 	return &SetServiceAccountOptions{ | 	return &SetServiceAccountOptions{ | ||||||
| 		PrintFlags:  printers.NewPrintFlags("serviceaccount updated", legacyscheme.Scheme), | 		PrintFlags:  printers.NewPrintFlags("serviceaccount updated").WithTypeSetter(scheme.Scheme), | ||||||
| 		RecordFlags: genericclioptions.NewRecordFlags(), | 		RecordFlags: genericclioptions.NewRecordFlags(), | ||||||
|  |  | ||||||
| 		Recorder: genericclioptions.NoopRecorder{}, | 		Recorder: genericclioptions.NoopRecorder{}, | ||||||
|   | |||||||
| @@ -90,12 +90,7 @@ func TestSetServiceAccountLocal(t *testing.T) { | |||||||
| 			cmd.Flags().Set("local", "true") | 			cmd.Flags().Set("local", "true") | ||||||
| 			testapi.Default = testapi.Groups[input.apiGroup] | 			testapi.Default = testapi.Groups[input.apiGroup] | ||||||
| 			saConfig := SetServiceAccountOptions{ | 			saConfig := SetServiceAccountOptions{ | ||||||
| 				PrintFlags: &printers.PrintFlags{ | 				PrintFlags: printers.NewPrintFlags("").WithDefaultOutput(outputFormat).WithTypeSetter(scheme.Scheme), | ||||||
| 					JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 					NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
|  |  | ||||||
| 					OutputFormat: &outputFormat, |  | ||||||
| 				}, |  | ||||||
| 				fileNameOptions: resource.FilenameOptions{ | 				fileNameOptions: resource.FilenameOptions{ | ||||||
| 					Filenames: []string{input.yaml}}, | 					Filenames: []string{input.yaml}}, | ||||||
| 				local:     true, | 				local:     true, | ||||||
| @@ -133,12 +128,7 @@ func TestSetServiceAccountMultiLocal(t *testing.T) { | |||||||
| 	cmd.Flags().Set("output", outputFormat) | 	cmd.Flags().Set("output", outputFormat) | ||||||
| 	cmd.Flags().Set("local", "true") | 	cmd.Flags().Set("local", "true") | ||||||
| 	opts := SetServiceAccountOptions{ | 	opts := SetServiceAccountOptions{ | ||||||
| 		PrintFlags: &printers.PrintFlags{ | 		PrintFlags: printers.NewPrintFlags("").WithDefaultOutput(outputFormat).WithTypeSetter(scheme.Scheme), | ||||||
| 			JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 			NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
|  |  | ||||||
| 			OutputFormat: &outputFormat, |  | ||||||
| 		}, |  | ||||||
| 		fileNameOptions: resource.FilenameOptions{ | 		fileNameOptions: resource.FilenameOptions{ | ||||||
| 			Filenames: []string{"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"}}, | 			Filenames: []string{"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"}}, | ||||||
| 		local:     true, | 		local:     true, | ||||||
| @@ -375,12 +365,7 @@ func TestSetServiceAccountRemote(t *testing.T) { | |||||||
| 			cmd := NewCmdServiceAccount(tf, streams) | 			cmd := NewCmdServiceAccount(tf, streams) | ||||||
| 			cmd.Flags().Set("output", outputFormat) | 			cmd.Flags().Set("output", outputFormat) | ||||||
| 			saConfig := SetServiceAccountOptions{ | 			saConfig := SetServiceAccountOptions{ | ||||||
| 				PrintFlags: &printers.PrintFlags{ | 				PrintFlags: printers.NewPrintFlags("").WithDefaultOutput(outputFormat).WithTypeSetter(scheme.Scheme), | ||||||
| 					JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 					NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
|  |  | ||||||
| 					OutputFormat: &outputFormat, |  | ||||||
| 				}, |  | ||||||
|  |  | ||||||
| 				local:     false, | 				local:     false, | ||||||
| 				IOStreams: streams, | 				IOStreams: streams, | ||||||
| @@ -422,12 +407,7 @@ func TestServiceAccountValidation(t *testing.T) { | |||||||
| 			cmd := NewCmdServiceAccount(tf, streams) | 			cmd := NewCmdServiceAccount(tf, streams) | ||||||
|  |  | ||||||
| 			saConfig := &SetServiceAccountOptions{ | 			saConfig := &SetServiceAccountOptions{ | ||||||
| 				PrintFlags: &printers.PrintFlags{ | 				PrintFlags: printers.NewPrintFlags("").WithDefaultOutput(outputFormat).WithTypeSetter(scheme.Scheme), | ||||||
| 					JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme), |  | ||||||
| 					NamePrintFlags:     printers.NewNamePrintFlags("", scheme.Scheme), |  | ||||||
|  |  | ||||||
| 					OutputFormat: &outputFormat, |  | ||||||
| 				}, |  | ||||||
| 				IOStreams:  streams, | 				IOStreams:  streams, | ||||||
| 			} | 			} | ||||||
| 			err := saConfig.Complete(tf, cmd, input.args) | 			err := saConfig.Complete(tf, cmd, input.args) | ||||||
|   | |||||||
| @@ -27,7 +27,6 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||||||
| 	"k8s.io/apimachinery/pkg/util/sets" | 	"k8s.io/apimachinery/pkg/util/sets" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	"k8s.io/kubernetes/pkg/apis/rbac" | 	"k8s.io/kubernetes/pkg/apis/rbac" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| @@ -83,7 +82,7 @@ type SubjectOptions struct { | |||||||
|  |  | ||||||
| func NewSubjectOptions(streams genericclioptions.IOStreams) *SubjectOptions { | func NewSubjectOptions(streams genericclioptions.IOStreams) *SubjectOptions { | ||||||
| 	return &SubjectOptions{ | 	return &SubjectOptions{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("subjects updated", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("subjects updated").WithTypeSetter(scheme.Scheme), | ||||||
|  |  | ||||||
| 		IOStreams: streams, | 		IOStreams: streams, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ import ( | |||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | 	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | 	"k8s.io/kubernetes/pkg/kubectl/util/i18n" | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| 	taintutils "k8s.io/kubernetes/pkg/util/taints" | 	taintutils "k8s.io/kubernetes/pkg/util/taints" | ||||||
| @@ -86,7 +87,7 @@ var ( | |||||||
|  |  | ||||||
| func NewCmdTaint(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { | func NewCmdTaint(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { | ||||||
| 	options := &TaintOptions{ | 	options := &TaintOptions{ | ||||||
| 		PrintFlags: printers.NewPrintFlags("tainted", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("tainted").WithTypeSetter(scheme.Scheme), | ||||||
| 		IOStreams:  streams, | 		IOStreams:  streams, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ go_library( | |||||||
|         "//build/visible_to:pkg_kubectl_cmd_util_editor_CONSUMERS", |         "//build/visible_to:pkg_kubectl_cmd_util_editor_CONSUMERS", | ||||||
|     ], |     ], | ||||||
|     deps = [ |     deps = [ | ||||||
|         "//pkg/api/legacyscheme:go_default_library", |  | ||||||
|         "//pkg/apis/core:go_default_library", |         "//pkg/apis/core:go_default_library", | ||||||
|         "//pkg/kubectl:go_default_library", |         "//pkg/kubectl:go_default_library", | ||||||
|         "//pkg/kubectl/cmd/util:go_default_library", |         "//pkg/kubectl/cmd/util:go_default_library", | ||||||
|   | |||||||
| @@ -42,7 +42,6 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/util/strategicpatch" | 	"k8s.io/apimachinery/pkg/util/strategicpatch" | ||||||
| 	"k8s.io/apimachinery/pkg/util/validation/field" | 	"k8s.io/apimachinery/pkg/util/validation/field" | ||||||
| 	"k8s.io/apimachinery/pkg/util/yaml" | 	"k8s.io/apimachinery/pkg/util/yaml" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | 	api "k8s.io/kubernetes/pkg/apis/core" | ||||||
| 	"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" | ||||||
| @@ -89,7 +88,7 @@ func NewEditOptions(editMode EditMode, ioStreams genericclioptions.IOStreams) *E | |||||||
|  |  | ||||||
| 		EditMode: editMode, | 		EditMode: editMode, | ||||||
|  |  | ||||||
| 		PrintFlags: printers.NewPrintFlags("edited", legacyscheme.Scheme), | 		PrintFlags: printers.NewPrintFlags("edited").WithTypeSetter(scheme.Scheme), | ||||||
|  |  | ||||||
| 		WindowsLineEndings: goruntime.GOOS == "windows", | 		WindowsLineEndings: goruntime.GOOS == "windows", | ||||||
|  |  | ||||||
|   | |||||||
| @@ -130,6 +130,7 @@ func (s SecretGeneratorV1) StructuredGenerate() (runtime.Object, error) { | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	secret := &v1.Secret{} | 	secret := &v1.Secret{} | ||||||
|  | 	secret.SetGroupVersionKind(v1.SchemeGroupVersion.WithKind("Secret")) | ||||||
| 	secret.Name = s.Name | 	secret.Name = s.Name | ||||||
| 	secret.Data = map[string][]byte{} | 	secret.Data = map[string][]byte{} | ||||||
| 	if len(s.Type) > 0 { | 	if len(s.Type) > 0 { | ||||||
|   | |||||||
| @@ -37,6 +37,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"name": "foo", | 				"name": "foo", | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "foo", | 					Name: "foo", | ||||||
| 				}, | 				}, | ||||||
| @@ -50,6 +52,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"append-hash": true, | 				"append-hash": true, | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "foo-949tdgdkgg", | 					Name: "foo-949tdgdkgg", | ||||||
| 				}, | 				}, | ||||||
| @@ -63,6 +67,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"type": "my-type", | 				"type": "my-type", | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "foo", | 					Name: "foo", | ||||||
| 				}, | 				}, | ||||||
| @@ -78,6 +84,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"append-hash": true, | 				"append-hash": true, | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "foo-dg474f9t76", | 					Name: "foo-dg474f9t76", | ||||||
| 				}, | 				}, | ||||||
| @@ -92,6 +100,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"from-literal": []string{"key1=value1", "key2=value2"}, | 				"from-literal": []string{"key1=value1", "key2=value2"}, | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "foo", | 					Name: "foo", | ||||||
| 				}, | 				}, | ||||||
| @@ -109,6 +119,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"append-hash":  true, | 				"append-hash":  true, | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "foo-tf72c228m4", | 					Name: "foo-tf72c228m4", | ||||||
| 				}, | 				}, | ||||||
| @@ -146,6 +158,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"from-literal": []string{"key1==value1"}, | 				"from-literal": []string{"key1==value1"}, | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "foo", | 					Name: "foo", | ||||||
| 				}, | 				}, | ||||||
| @@ -162,6 +176,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"append-hash":  true, | 				"append-hash":  true, | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "foo-fdcc8tkhh5", | 					Name: "foo-fdcc8tkhh5", | ||||||
| 				}, | 				}, | ||||||
| @@ -178,6 +194,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"from-env-file": "file.env", | 				"from-env-file": "file.env", | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "valid_env", | 					Name: "valid_env", | ||||||
| 				}, | 				}, | ||||||
| @@ -196,6 +214,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"append-hash":   true, | 				"append-hash":   true, | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "valid_env-bkb2m2965h", | 					Name: "valid_env-bkb2m2965h", | ||||||
| 				}, | 				}, | ||||||
| @@ -217,6 +237,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"from-env-file": "file.env", | 				"from-env-file": "file.env", | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "getenv", | 					Name: "getenv", | ||||||
| 				}, | 				}, | ||||||
| @@ -239,6 +261,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"append-hash":   true, | 				"append-hash":   true, | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "getenv-m7kg2khdb4", | 					Name: "getenv-m7kg2khdb4", | ||||||
| 				}, | 				}, | ||||||
| @@ -272,6 +296,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"from-env-file": "file.env", | 				"from-env-file": "file.env", | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "with_spaces", | 					Name: "with_spaces", | ||||||
| 				}, | 				}, | ||||||
| @@ -289,6 +315,8 @@ func TestSecretGenerate(t *testing.T) { | |||||||
| 				"append-hash":   true, | 				"append-hash":   true, | ||||||
| 			}, | 			}, | ||||||
| 			expected: &v1.Secret{ | 			expected: &v1.Secret{ | ||||||
|  | 				// this is ok because we know exactly how we want to be serialized | ||||||
|  | 				TypeMeta: metav1.TypeMeta{APIVersion: v1.SchemeGroupVersion.String(), Kind: "Secret"}, | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
| 					Name: "with_spaces-4488d5b57d", | 					Name: "with_spaces-4488d5b57d", | ||||||
| 				}, | 				}, | ||||||
|   | |||||||
| @@ -24,14 +24,12 @@ go_library( | |||||||
|         "tabwriter.go", |         "tabwriter.go", | ||||||
|         "template.go", |         "template.go", | ||||||
|         "template_flags.go", |         "template_flags.go", | ||||||
|         "versioned.go", |         "typesetter.go", | ||||||
|     ], |     ], | ||||||
|     importpath = "k8s.io/kubernetes/pkg/printers", |     importpath = "k8s.io/kubernetes/pkg/printers", | ||||||
|     deps = [ |     deps = [ | ||||||
|         "//pkg/api/legacyscheme:go_default_library", |  | ||||||
|         "//pkg/kubectl/scheme:go_default_library", |         "//pkg/kubectl/scheme:go_default_library", | ||||||
|         "//vendor/github.com/ghodss/yaml:go_default_library", |         "//vendor/github.com/ghodss/yaml:go_default_library", | ||||||
|         "//vendor/github.com/golang/glog:go_default_library", |  | ||||||
|         "//vendor/github.com/spf13/cobra:go_default_library", |         "//vendor/github.com/spf13/cobra:go_default_library", | ||||||
|         "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", |         "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", | ||||||
|         "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", |         "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", | ||||||
|   | |||||||
| @@ -23,7 +23,6 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/scheme" | 	"k8s.io/kubernetes/pkg/kubectl/scheme" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -84,7 +83,7 @@ func (f *CustomColumnsPrintFlags) ToPrinter(templateFormat string) (ResourcePrin | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	p, err := NewCustomColumnsPrinterFromSpec(templateValue, decoder, f.NoHeaders) | 	p, err := NewCustomColumnsPrinterFromSpec(templateValue, decoder, f.NoHeaders) | ||||||
| 	return NewVersionedPrinter(p, legacyscheme.Scheme, legacyscheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...), err | 	return p, err | ||||||
| } | } | ||||||
|  |  | ||||||
| // AddFlags receives a *cobra.Command reference and binds | // AddFlags receives a *cobra.Command reference and binds | ||||||
|   | |||||||
| @@ -21,7 +21,6 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -75,6 +74,8 @@ type PrintFlags struct { | |||||||
| 	JSONYamlPrintFlags *JSONYamlPrintFlags | 	JSONYamlPrintFlags *JSONYamlPrintFlags | ||||||
| 	NamePrintFlags     *NamePrintFlags | 	NamePrintFlags     *NamePrintFlags | ||||||
|  |  | ||||||
|  | 	TypeSetterPrinter *TypeSetterPrinter | ||||||
|  |  | ||||||
| 	OutputFormat *string | 	OutputFormat *string | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -90,13 +91,13 @@ func (f *PrintFlags) ToPrinter() (ResourcePrinter, error) { | |||||||
|  |  | ||||||
| 	if f.JSONYamlPrintFlags != nil { | 	if f.JSONYamlPrintFlags != nil { | ||||||
| 		if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) { | 		if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) { | ||||||
| 			return p, err | 			return f.TypeSetterPrinter.WrapToPrinter(p, err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if f.NamePrintFlags != nil { | 	if f.NamePrintFlags != nil { | ||||||
| 		if p, err := f.NamePrintFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) { | 		if p, err := f.NamePrintFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) { | ||||||
| 			return p, err | 			return f.TypeSetterPrinter.WrapToPrinter(p, err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -118,14 +119,20 @@ func (f *PrintFlags) WithDefaultOutput(output string) *PrintFlags { | |||||||
| 	return f | 	return f | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewPrintFlags(operation string, scheme runtime.ObjectConvertor) *PrintFlags { | // WithTypeSetter sets a wrapper than will surround the returned printer with a printer to type resources | ||||||
|  | func (f *PrintFlags) WithTypeSetter(scheme *runtime.Scheme) *PrintFlags { | ||||||
|  | 	f.TypeSetterPrinter = NewTypeSetter(scheme) | ||||||
|  | 	return f | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func NewPrintFlags(operation string) *PrintFlags { | ||||||
| 	outputFormat := "" | 	outputFormat := "" | ||||||
|  |  | ||||||
| 	return &PrintFlags{ | 	return &PrintFlags{ | ||||||
| 		OutputFormat: &outputFormat, | 		OutputFormat: &outputFormat, | ||||||
|  |  | ||||||
| 		JSONYamlPrintFlags: NewJSONYamlPrintFlags(scheme), | 		JSONYamlPrintFlags: NewJSONYamlPrintFlags(), | ||||||
| 		NamePrintFlags:     NewNamePrintFlags(operation, scheme), | 		NamePrintFlags:     NewNamePrintFlags(operation), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -59,6 +59,7 @@ func init() { | |||||||
| } | } | ||||||
|  |  | ||||||
| var testData = TestStruct{ | var testData = TestStruct{ | ||||||
|  | 	TypeMeta:   metav1.TypeMeta{APIVersion: "foo/bar", Kind: "TestStruct"}, | ||||||
| 	Key:        "testValue", | 	Key:        "testValue", | ||||||
| 	Map:        map[string]int{"TestSubkey": 1}, | 	Map:        map[string]int{"TestSubkey": 1}, | ||||||
| 	StringList: []string{"a", "b", "c"}, | 	StringList: []string{"a", "b", "c"}, | ||||||
| @@ -78,27 +79,6 @@ func (in *TestStruct) DeepCopyObject() runtime.Object { | |||||||
| 	panic("never called") | 	panic("never called") | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestVersionedPrinter(t *testing.T) { |  | ||||||
| 	original := &TestPrintType{Data: "value"} |  | ||||||
| 	p := printers.NewVersionedPrinter( |  | ||||||
| 		printers.ResourcePrinterFunc(func(obj runtime.Object, w io.Writer) error { |  | ||||||
| 			if obj == original { |  | ||||||
| 				t.Fatalf("object should not be identical: %#v", obj) |  | ||||||
| 			} |  | ||||||
| 			if obj.(*TestPrintType).Data != "value" { |  | ||||||
| 				t.Fatalf("object was not converted: %#v", obj) |  | ||||||
| 			} |  | ||||||
| 			return nil |  | ||||||
| 		}), |  | ||||||
| 		legacyscheme.Scheme, |  | ||||||
| 		legacyscheme.Scheme, |  | ||||||
| 		schema.GroupVersion{Group: "", Version: "v1"}, |  | ||||||
| 	) |  | ||||||
| 	if err := p.PrintObj(original, nil); err != nil { |  | ||||||
| 		t.Errorf("unexpected error: %v", err) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestPrintUnstructuredObject(t *testing.T) { | func TestPrintUnstructuredObject(t *testing.T) { | ||||||
| 	obj := &unstructured.Unstructured{ | 	obj := &unstructured.Unstructured{ | ||||||
| 		Object: map[string]interface{}{ | 		Object: map[string]interface{}{ | ||||||
| @@ -253,6 +233,7 @@ func testPrinter(t *testing.T, printer printers.ResourcePrinter, unmarshalFunc f | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	obj := &v1.Pod{ | 	obj := &v1.Pod{ | ||||||
|  | 		TypeMeta:   metav1.TypeMeta{APIVersion: "v1", Kind: "Pod"}, | ||||||
| 		ObjectMeta: metav1.ObjectMeta{Name: "foo"}, | 		ObjectMeta: metav1.ObjectMeta{Name: "foo"}, | ||||||
| 	} | 	} | ||||||
| 	buf.Reset() | 	buf.Reset() | ||||||
| @@ -274,11 +255,11 @@ func testPrinter(t *testing.T, printer printers.ResourcePrinter, unmarshalFunc f | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestYAMLPrinter(t *testing.T) { | func TestYAMLPrinter(t *testing.T) { | ||||||
| 	testPrinter(t, &printers.YAMLPrinter{}, yaml.Unmarshal) | 	testPrinter(t, printers.NewTypeSetter(legacyscheme.Scheme).ToPrinter(&printers.YAMLPrinter{}), yaml.Unmarshal) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestJSONPrinter(t *testing.T) { | func TestJSONPrinter(t *testing.T) { | ||||||
| 	testPrinter(t, &printers.JSONPrinter{}, json.Unmarshal) | 	testPrinter(t, printers.NewTypeSetter(legacyscheme.Scheme).ToPrinter(&printers.JSONPrinter{}), json.Unmarshal) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestFormatResourceName(t *testing.T) { | func TestFormatResourceName(t *testing.T) { | ||||||
| @@ -384,23 +365,13 @@ func TestNamePrinter(t *testing.T) { | |||||||
| 			}, | 			}, | ||||||
| 			"pod/foo\n"}, | 			"pod/foo\n"}, | ||||||
| 		"List": { | 		"List": { | ||||||
| 			&v1.List{ | 			&unstructured.UnstructuredList{ | ||||||
| 				TypeMeta: metav1.TypeMeta{ | 				Object: map[string]interface{}{ | ||||||
| 					Kind: "List", | 					"kind":       "List", | ||||||
|  | 					"apiVersion": "v1", | ||||||
| 				}, | 				}, | ||||||
| 				Items: []runtime.RawExtension{ | 				Items: []unstructured.Unstructured{ | ||||||
| 					{ | 					{ | ||||||
| 						Object: &v1.Pod{ |  | ||||||
| 							TypeMeta: metav1.TypeMeta{ |  | ||||||
| 								Kind: "Pod", |  | ||||||
| 							}, |  | ||||||
| 							ObjectMeta: metav1.ObjectMeta{ |  | ||||||
| 								Name: "foo", |  | ||||||
| 							}, |  | ||||||
| 						}, |  | ||||||
| 					}, |  | ||||||
| 					{ |  | ||||||
| 						Object: &unstructured.Unstructured{ |  | ||||||
| 						Object: map[string]interface{}{ | 						Object: map[string]interface{}{ | ||||||
| 							"kind":       "Pod", | 							"kind":       "Pod", | ||||||
| 							"apiVersion": "v1", | 							"apiVersion": "v1", | ||||||
| @@ -411,11 +382,10 @@ func TestNamePrinter(t *testing.T) { | |||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			}, | 			"pod/bar\n"}, | ||||||
| 			"pod/foo\npod/bar\n"}, |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	printFlags := printers.NewPrintFlags("", legacyscheme.Scheme).WithDefaultOutput("name") | 	printFlags := printers.NewPrintFlags("").WithTypeSetter(legacyscheme.Scheme).WithDefaultOutput("name") | ||||||
| 	printer, err := printFlags.ToPrinter() | 	printer, err := printFlags.ToPrinter() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("unexpected err: %v", err) | 		t.Fatalf("unexpected err: %v", err) | ||||||
| @@ -438,15 +408,15 @@ func TestNamePrinter(t *testing.T) { | |||||||
| func TestTemplateStrings(t *testing.T) { | func TestTemplateStrings(t *testing.T) { | ||||||
| 	// This unit tests the "exists" function as well as the template from update.sh | 	// This unit tests the "exists" function as well as the template from update.sh | ||||||
| 	table := map[string]struct { | 	table := map[string]struct { | ||||||
| 		pod    api.Pod | 		pod    v1.Pod | ||||||
| 		expect string | 		expect string | ||||||
| 	}{ | 	}{ | ||||||
| 		"nilInfo":   {api.Pod{}, "false"}, | 		"nilInfo":   {v1.Pod{}, "false"}, | ||||||
| 		"emptyInfo": {api.Pod{Status: api.PodStatus{ContainerStatuses: []api.ContainerStatus{}}}, "false"}, | 		"emptyInfo": {v1.Pod{Status: v1.PodStatus{ContainerStatuses: []v1.ContainerStatus{}}}, "false"}, | ||||||
| 		"fooExists": { | 		"fooExists": { | ||||||
| 			api.Pod{ | 			v1.Pod{ | ||||||
| 				Status: api.PodStatus{ | 				Status: v1.PodStatus{ | ||||||
| 					ContainerStatuses: []api.ContainerStatus{ | 					ContainerStatuses: []v1.ContainerStatus{ | ||||||
| 						{ | 						{ | ||||||
| 							Name: "foo", | 							Name: "foo", | ||||||
| 						}, | 						}, | ||||||
| @@ -456,9 +426,9 @@ func TestTemplateStrings(t *testing.T) { | |||||||
| 			"false", | 			"false", | ||||||
| 		}, | 		}, | ||||||
| 		"barExists": { | 		"barExists": { | ||||||
| 			api.Pod{ | 			v1.Pod{ | ||||||
| 				Status: api.PodStatus{ | 				Status: v1.PodStatus{ | ||||||
| 					ContainerStatuses: []api.ContainerStatus{ | 					ContainerStatuses: []v1.ContainerStatus{ | ||||||
| 						{ | 						{ | ||||||
| 							Name: "bar", | 							Name: "bar", | ||||||
| 						}, | 						}, | ||||||
| @@ -468,9 +438,9 @@ func TestTemplateStrings(t *testing.T) { | |||||||
| 			"false", | 			"false", | ||||||
| 		}, | 		}, | ||||||
| 		"bothExist": { | 		"bothExist": { | ||||||
| 			api.Pod{ | 			v1.Pod{ | ||||||
| 				Status: api.PodStatus{ | 				Status: v1.PodStatus{ | ||||||
| 					ContainerStatuses: []api.ContainerStatus{ | 					ContainerStatuses: []v1.ContainerStatus{ | ||||||
| 						{ | 						{ | ||||||
| 							Name: "foo", | 							Name: "foo", | ||||||
| 						}, | 						}, | ||||||
| @@ -483,16 +453,16 @@ func TestTemplateStrings(t *testing.T) { | |||||||
| 			"false", | 			"false", | ||||||
| 		}, | 		}, | ||||||
| 		"barValid": { | 		"barValid": { | ||||||
| 			api.Pod{ | 			v1.Pod{ | ||||||
| 				Status: api.PodStatus{ | 				Status: v1.PodStatus{ | ||||||
| 					ContainerStatuses: []api.ContainerStatus{ | 					ContainerStatuses: []v1.ContainerStatus{ | ||||||
| 						{ | 						{ | ||||||
| 							Name: "foo", | 							Name: "foo", | ||||||
| 						}, | 						}, | ||||||
| 						{ | 						{ | ||||||
| 							Name: "bar", | 							Name: "bar", | ||||||
| 							State: api.ContainerState{ | 							State: v1.ContainerState{ | ||||||
| 								Running: &api.ContainerStateRunning{ | 								Running: &v1.ContainerStateRunning{ | ||||||
| 									StartedAt: metav1.Time{}, | 									StartedAt: metav1.Time{}, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| @@ -503,21 +473,21 @@ func TestTemplateStrings(t *testing.T) { | |||||||
| 			"false", | 			"false", | ||||||
| 		}, | 		}, | ||||||
| 		"bothValid": { | 		"bothValid": { | ||||||
| 			api.Pod{ | 			v1.Pod{ | ||||||
| 				Status: api.PodStatus{ | 				Status: v1.PodStatus{ | ||||||
| 					ContainerStatuses: []api.ContainerStatus{ | 					ContainerStatuses: []v1.ContainerStatus{ | ||||||
| 						{ | 						{ | ||||||
| 							Name: "foo", | 							Name: "foo", | ||||||
| 							State: api.ContainerState{ | 							State: v1.ContainerState{ | ||||||
| 								Running: &api.ContainerStateRunning{ | 								Running: &v1.ContainerStateRunning{ | ||||||
| 									StartedAt: metav1.Time{}, | 									StartedAt: metav1.Time{}, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
| 						{ | 						{ | ||||||
| 							Name: "bar", | 							Name: "bar", | ||||||
| 							State: api.ContainerState{ | 							State: v1.ContainerState{ | ||||||
| 								Running: &api.ContainerStateRunning{ | 								Running: &v1.ContainerStateRunning{ | ||||||
| 									StartedAt: metav1.Time{}, | 									StartedAt: metav1.Time{}, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| @@ -530,13 +500,11 @@ func TestTemplateStrings(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 	// The point of this test is to verify that the below template works. | 	// The point of this test is to verify that the below template works. | ||||||
| 	tmpl := `{{if (exists . "status" "containerStatuses")}}{{range .status.containerStatuses}}{{if (and (eq .name "foo") (exists . "state" "running"))}}true{{end}}{{end}}{{end}}` | 	tmpl := `{{if (exists . "status" "containerStatuses")}}{{range .status.containerStatuses}}{{if (and (eq .name "foo") (exists . "state" "running"))}}true{{end}}{{end}}{{end}}` | ||||||
| 	p, err := printers.NewGoTemplatePrinter([]byte(tmpl)) | 	printer, err := printers.NewGoTemplatePrinter([]byte(tmpl)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("tmpl fail: %v", err) | 		t.Fatalf("tmpl fail: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	printer := printers.NewVersionedPrinter(p, legacyscheme.Scheme, legacyscheme.Scheme, schema.GroupVersion{Group: "", Version: "v1"}) |  | ||||||
|  |  | ||||||
| 	for name, item := range table { | 	for name, item := range table { | ||||||
| 		buffer := &bytes.Buffer{} | 		buffer := &bytes.Buffer{} | ||||||
| 		err = printer.PrintObj(&item.pod, buffer) | 		err = printer.PrintObj(&item.pod, buffer) | ||||||
| @@ -568,29 +536,23 @@ func TestPrinters(t *testing.T) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	templatePrinter = printers.NewVersionedPrinter(templatePrinter, legacyscheme.Scheme, legacyscheme.Scheme, v1.SchemeGroupVersion) |  | ||||||
|  |  | ||||||
| 	templatePrinter2, err = printers.NewGoTemplatePrinter([]byte("{{len .items}}")) | 	templatePrinter2, err = printers.NewGoTemplatePrinter([]byte("{{len .items}}")) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	templatePrinter2 = printers.NewVersionedPrinter(templatePrinter2, legacyscheme.Scheme, legacyscheme.Scheme, v1.SchemeGroupVersion) |  | ||||||
|  |  | ||||||
| 	jsonpathPrinter, err = printers.NewJSONPathPrinter("{.metadata.name}") | 	jsonpathPrinter, err = printers.NewJSONPathPrinter("{.metadata.name}") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	jsonpathPrinter = printers.NewVersionedPrinter(jsonpathPrinter, legacyscheme.Scheme, legacyscheme.Scheme, v1.SchemeGroupVersion) |  | ||||||
|  |  | ||||||
| 	genericPrinters := map[string]printers.ResourcePrinter{ | 	genericPrinters := map[string]printers.ResourcePrinter{ | ||||||
| 		"json":      &printers.JSONPrinter{}, | 		"json":      printers.NewTypeSetter(legacyscheme.Scheme).ToPrinter(&printers.JSONPrinter{}), | ||||||
| 		"yaml":      &printers.YAMLPrinter{}, | 		"yaml":      printers.NewTypeSetter(legacyscheme.Scheme).ToPrinter(&printers.YAMLPrinter{}), | ||||||
| 		"template":  templatePrinter, | 		"template":  templatePrinter, | ||||||
| 		"template2": templatePrinter2, | 		"template2": templatePrinter2, | ||||||
| 		"jsonpath":  jsonpathPrinter, | 		"jsonpath":  jsonpathPrinter, | ||||||
| 		"name": &printers.NamePrinter{ |  | ||||||
| 			Typer: legacyscheme.Scheme, |  | ||||||
| 		}, |  | ||||||
| 	} | 	} | ||||||
| 	objects := map[string]runtime.Object{ | 	objects := map[string]runtime.Object{ | ||||||
| 		"pod":             &v1.Pod{ObjectMeta: om("pod")}, | 		"pod":             &v1.Pod{ObjectMeta: om("pod")}, | ||||||
|   | |||||||
| @@ -52,6 +52,10 @@ func (p *JSONPrinter) PrintObj(obj runtime.Object, w io.Writer) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if obj.GetObjectKind().GroupVersionKind().Empty() { | ||||||
|  | 		return fmt.Errorf("missing apiVersion or kind; try GetObjectKind().SetGroupVersionKind() if you know the type") | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	data, err := json.MarshalIndent(obj, "", "    ") | 	data, err := json.MarshalIndent(obj, "", "    ") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -88,6 +92,10 @@ func (p *YAMLPrinter) PrintObj(obj runtime.Object, w io.Writer) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if obj.GetObjectKind().GroupVersionKind().Empty() { | ||||||
|  | 		return fmt.Errorf("missing apiVersion or kind; try GetObjectKind().SetGroupVersionKind() if you know the type") | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	output, err := yaml.Marshal(obj) | 	output, err := yaml.Marshal(obj) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
|   | |||||||
| @@ -20,16 +20,12 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" |  | ||||||
| 	kubectlscheme "k8s.io/kubernetes/pkg/kubectl/scheme" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // JSONYamlPrintFlags provides default flags necessary for json/yaml printing. | // JSONYamlPrintFlags provides default flags necessary for json/yaml printing. | ||||||
| // Given the following flag values, a printer can be requested that knows | // Given the following flag values, a printer can be requested that knows | ||||||
| // how to handle printing based on these values. | // how to handle printing based on these values. | ||||||
| type JSONYamlPrintFlags struct { | type JSONYamlPrintFlags struct { | ||||||
| 	Scheme runtime.ObjectConvertor |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // ToPrinter receives an outputFormat and returns a printer capable of | // ToPrinter receives an outputFormat and returns a printer capable of | ||||||
| @@ -49,9 +45,7 @@ func (f *JSONYamlPrintFlags) ToPrinter(outputFormat string) (ResourcePrinter, er | |||||||
| 		return nil, NoCompatiblePrinterError{Options: f, OutputFormat: &outputFormat} | 		return nil, NoCompatiblePrinterError{Options: f, OutputFormat: &outputFormat} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// wrap the printer in a versioning printer that understands when to convert and when not to convert | 	return printer, nil | ||||||
| 	return NewVersionedPrinter(printer, f.Scheme, f.Scheme.(runtime.ObjectTyper), kubectlscheme.Scheme.PrioritizedVersionsAllGroups()...), nil |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // AddFlags receives a *cobra.Command reference and binds | // AddFlags receives a *cobra.Command reference and binds | ||||||
| @@ -60,6 +54,6 @@ func (f *JSONYamlPrintFlags) AddFlags(c *cobra.Command) {} | |||||||
|  |  | ||||||
| // NewJSONYamlPrintFlags returns flags associated with | // NewJSONYamlPrintFlags returns flags associated with | ||||||
| // yaml or json printing, with default values set. | // yaml or json printing, with default values set. | ||||||
| func NewJSONYamlPrintFlags(scheme runtime.ObjectConvertor) *JSONYamlPrintFlags { | func NewJSONYamlPrintFlags() *JSONYamlPrintFlags { | ||||||
| 	return &JSONYamlPrintFlags{Scheme: scheme} | 	return &JSONYamlPrintFlags{} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -23,12 +23,14 @@ import ( | |||||||
|  |  | ||||||
| 	"k8s.io/api/core/v1" | 	"k8s.io/api/core/v1" | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" |  | ||||||
| 	"k8s.io/kubernetes/pkg/printers" | 	"k8s.io/kubernetes/pkg/printers" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestPrinterSupportsExpectedJSONYamlFormats(t *testing.T) { | func TestPrinterSupportsExpectedJSONYamlFormats(t *testing.T) { | ||||||
| 	testObject := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}} | 	testObject := &v1.Pod{ | ||||||
|  | 		TypeMeta:   metav1.TypeMeta{APIVersion: "v1", Kind: "Pod"}, | ||||||
|  | 		ObjectMeta: metav1.ObjectMeta{Name: "foo"}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	testCases := []struct { | 	testCases := []struct { | ||||||
| 		name           string | 		name           string | ||||||
| @@ -60,7 +62,7 @@ func TestPrinterSupportsExpectedJSONYamlFormats(t *testing.T) { | |||||||
|  |  | ||||||
| 	for _, tc := range testCases { | 	for _, tc := range testCases { | ||||||
| 		t.Run(tc.name, func(t *testing.T) { | 		t.Run(tc.name, func(t *testing.T) { | ||||||
| 			printFlags := printers.JSONYamlPrintFlags{Scheme: legacyscheme.Scheme} | 			printFlags := printers.JSONYamlPrintFlags{} | ||||||
|  |  | ||||||
| 			p, err := printFlags.ToPrinter(tc.outputFormat) | 			p, err := printFlags.ToPrinter(tc.outputFormat) | ||||||
| 			if tc.expectNoMatch { | 			if tc.expectNoMatch { | ||||||
|   | |||||||
| @@ -37,8 +37,6 @@ type NamePrinter struct { | |||||||
| 	// took place on an object, to be included in the | 	// took place on an object, to be included in the | ||||||
| 	// finalized "successful" message. | 	// finalized "successful" message. | ||||||
| 	Operation string | 	Operation string | ||||||
|  |  | ||||||
| 	Typer runtime.ObjectTyper |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // PrintObj is an implementation of ResourcePrinter.PrintObj which decodes the object | // PrintObj is an implementation of ResourcePrinter.PrintObj which decodes the object | ||||||
| @@ -52,6 +50,13 @@ func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if meta.IsListType(obj) { | 	if meta.IsListType(obj) { | ||||||
|  | 		// we allow unstructured lists for now because they always contain the GVK information.  We should chase down | ||||||
|  | 		// callers and stop them from passing unflattened lists | ||||||
|  | 		// TODO chase the caller that is setting this and remove it. | ||||||
|  | 		if _, ok := obj.(*unstructured.UnstructuredList); !ok { | ||||||
|  | 			return fmt.Errorf("list types are not supported by name printing: %T", obj) | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		items, err := meta.ExtractList(obj) | 		items, err := meta.ExtractList(obj) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| @@ -64,6 +69,10 @@ func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if obj.GetObjectKind().GroupVersionKind().Empty() { | ||||||
|  | 		return fmt.Errorf("missing apiVersion or kind; try GetObjectKind().SetGroupVersionKind() if you know the type") | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	name := "<unknown>" | 	name := "<unknown>" | ||||||
| 	if acc, err := meta.Accessor(obj); err == nil { | 	if acc, err := meta.Accessor(obj); err == nil { | ||||||
| 		if n := acc.GetName(); len(n) > 0 { | 		if n := acc.GetName(); len(n) > 0 { | ||||||
| @@ -71,10 +80,10 @@ func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return printObj(w, name, p.Operation, p.ShortOutput, GetObjectGroupKind(obj, p.Typer)) | 	return printObj(w, name, p.Operation, p.ShortOutput, GetObjectGroupKind(obj)) | ||||||
| } | } | ||||||
|  |  | ||||||
| func GetObjectGroupKind(obj runtime.Object, typer runtime.ObjectTyper) schema.GroupKind { | func GetObjectGroupKind(obj runtime.Object) schema.GroupKind { | ||||||
| 	if obj == nil { | 	if obj == nil { | ||||||
| 		return schema.GroupKind{Kind: "<unknown>"} | 		return schema.GroupKind{Kind: "<unknown>"} | ||||||
| 	} | 	} | ||||||
| @@ -83,15 +92,6 @@ func GetObjectGroupKind(obj runtime.Object, typer runtime.ObjectTyper) schema.Gr | |||||||
| 		return groupVersionKind.GroupKind() | 		return groupVersionKind.GroupKind() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if gvks, _, err := typer.ObjectKinds(obj); err == nil { |  | ||||||
| 		for _, gvk := range gvks { |  | ||||||
| 			if len(gvk.Kind) == 0 { |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 			return gvk.GroupKind() |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if uns, ok := obj.(*unstructured.Unstructured); ok { | 	if uns, ok := obj.(*unstructured.Unstructured); ok { | ||||||
| 		if len(uns.GroupVersionKind().Kind) > 0 { | 		if len(uns.GroupVersionKind().Kind) > 0 { | ||||||
| 			return uns.GroupVersionKind().GroupKind() | 			return uns.GroupVersionKind().GroupKind() | ||||||
|   | |||||||
| @@ -21,18 +21,12 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" |  | ||||||
|  |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/scheme" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // NamePrintFlags provides default flags necessary for printing | // NamePrintFlags provides default flags necessary for printing | ||||||
| // a resource's fully-qualified Kind.group/name, or a successful | // a resource's fully-qualified Kind.group/name, or a successful | ||||||
| // message about that resource if an Operation is provided. | // message about that resource if an Operation is provided. | ||||||
| type NamePrintFlags struct { | type NamePrintFlags struct { | ||||||
| 	Scheme runtime.ObjectConvertor |  | ||||||
|  |  | ||||||
| 	// Operation describes the name of the action that | 	// Operation describes the name of the action that | ||||||
| 	// took place on an object, to be included in the | 	// took place on an object, to be included in the | ||||||
| 	// finalized "successful" message. | 	// finalized "successful" message. | ||||||
| @@ -51,7 +45,6 @@ func (f *NamePrintFlags) Complete(successTemplate string) error { | |||||||
| func (f *NamePrintFlags) ToPrinter(outputFormat string) (ResourcePrinter, error) { | func (f *NamePrintFlags) ToPrinter(outputFormat string) (ResourcePrinter, error) { | ||||||
| 	namePrinter := &NamePrinter{ | 	namePrinter := &NamePrinter{ | ||||||
| 		Operation: f.Operation, | 		Operation: f.Operation, | ||||||
| 		Typer:     scheme.Scheme, |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	outputFormat = strings.ToLower(outputFormat) | 	outputFormat = strings.ToLower(outputFormat) | ||||||
| @@ -72,7 +65,7 @@ func (f *NamePrintFlags) AddFlags(c *cobra.Command) {} | |||||||
|  |  | ||||||
| // NewNamePrintFlags returns flags associated with | // NewNamePrintFlags returns flags associated with | ||||||
| // --name printing, with default values set. | // --name printing, with default values set. | ||||||
| func NewNamePrintFlags(operation string, scheme runtime.ObjectConvertor) *NamePrintFlags { | func NewNamePrintFlags(operation string) *NamePrintFlags { | ||||||
| 	return &NamePrintFlags{ | 	return &NamePrintFlags{ | ||||||
| 		Operation: operation, | 		Operation: operation, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -27,7 +27,10 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestNamePrinterSupportsExpectedFormats(t *testing.T) { | func TestNamePrinterSupportsExpectedFormats(t *testing.T) { | ||||||
| 	testObject := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}} | 	testObject := &v1.Pod{ | ||||||
|  | 		TypeMeta:   metav1.TypeMeta{APIVersion: "v1", Kind: "Pod"}, | ||||||
|  | 		ObjectMeta: metav1.ObjectMeta{Name: "foo"}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	testCases := []struct { | 	testCases := []struct { | ||||||
| 		name           string | 		name           string | ||||||
|   | |||||||
							
								
								
									
										95
									
								
								pkg/printers/typesetter.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								pkg/printers/typesetter.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | |||||||
|  | /* | ||||||
|  | Copyright 2018 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 printers | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  |  | ||||||
|  | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
|  | 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // TypeSetterPrinter is an implementation of ResourcePrinter wraps another printer with types set on the objects | ||||||
|  | type TypeSetterPrinter struct { | ||||||
|  | 	Delegate ResourcePrinter | ||||||
|  |  | ||||||
|  | 	Typer runtime.ObjectTyper | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewTypeSetter constructs a wrapping printer with required params | ||||||
|  | func NewTypeSetter(typer runtime.ObjectTyper) *TypeSetterPrinter { | ||||||
|  | 	return &TypeSetterPrinter{Typer: typer} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // PrintObj is an implementation of ResourcePrinter.PrintObj which sets type information on the obj for the duration | ||||||
|  | // of printing.  It is NOT threadsafe. | ||||||
|  | func (p *TypeSetterPrinter) PrintObj(obj runtime.Object, w io.Writer) error { | ||||||
|  | 	if obj == nil { | ||||||
|  | 		return p.Delegate.PrintObj(obj, w) | ||||||
|  | 	} | ||||||
|  | 	if !obj.GetObjectKind().GroupVersionKind().Empty() { | ||||||
|  | 		return p.Delegate.PrintObj(obj, w) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// we were empty coming in, make sure we're empty going out.  This makes the call thread-unsafe | ||||||
|  | 	defer func() { | ||||||
|  | 		obj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{}) | ||||||
|  | 	}() | ||||||
|  |  | ||||||
|  | 	gvks, _, err := p.Typer.ObjectKinds(obj) | ||||||
|  | 	if err != nil { | ||||||
|  | 		// printers wrapped by us expect to find the type information present | ||||||
|  | 		return fmt.Errorf("missing apiVersion or kind and cannot assign it; %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for _, gvk := range gvks { | ||||||
|  | 		if len(gvk.Kind) == 0 { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		if len(gvk.Version) == 0 || gvk.Version == runtime.APIVersionInternal { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		obj.GetObjectKind().SetGroupVersionKind(gvk) | ||||||
|  | 		break | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return p.Delegate.PrintObj(obj, w) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ToPrinter returns a printer (not threadsafe!) that has been wrapped | ||||||
|  | func (p *TypeSetterPrinter) ToPrinter(delegate ResourcePrinter) ResourcePrinter { | ||||||
|  | 	if p == nil { | ||||||
|  | 		return delegate | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	p.Delegate = delegate | ||||||
|  | 	return p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // WrapToPrinter wraps the common ToPrinter method | ||||||
|  | func (p *TypeSetterPrinter) WrapToPrinter(delegate ResourcePrinter, err error) (ResourcePrinter, error) { | ||||||
|  | 	if err != nil { | ||||||
|  | 		return delegate, err | ||||||
|  | 	} | ||||||
|  | 	if p == nil { | ||||||
|  | 		return delegate, nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	p.Delegate = delegate | ||||||
|  | 	return p, nil | ||||||
|  | } | ||||||
| @@ -1,85 +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 printers |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
|  |  | ||||||
| 	"github.com/golang/glog" |  | ||||||
| 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" |  | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" |  | ||||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // VersionedPrinter takes runtime objects and ensures they are converted to a given API version |  | ||||||
| // prior to being passed to a nested printer. |  | ||||||
| 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, typer runtime.ObjectTyper, versions ...schema.GroupVersion) ResourcePrinter { |  | ||||||
| 	return &VersionedPrinter{ |  | ||||||
| 		printer:   printer, |  | ||||||
| 		converter: converter, |  | ||||||
| 		typer:     typer, |  | ||||||
| 		versions:  versions, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // PrintObj implements ResourcePrinter |  | ||||||
| func (p *VersionedPrinter) PrintObj(obj runtime.Object, w io.Writer) error { |  | ||||||
| 	// if we're unstructured, no conversion necessary |  | ||||||
| 	if _, ok := obj.(*unstructured.Unstructured); ok { |  | ||||||
| 		return p.printer.PrintObj(obj, w) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// if we're already external, no conversion necessary |  | ||||||
| 	gvks, _, err := p.typer.ObjectKinds(obj) |  | ||||||
| 	if err != nil { |  | ||||||
| 		glog.V(1).Infof("error determining type for %T, using passed object: %v", obj, err) |  | ||||||
| 		return p.printer.PrintObj(obj, w) |  | ||||||
| 	} |  | ||||||
| 	needsConversion := false |  | ||||||
| 	for _, gvk := range gvks { |  | ||||||
| 		if len(gvk.Version) == 0 || gvk.Version == runtime.APIVersionInternal { |  | ||||||
| 			needsConversion = true |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if !needsConversion { |  | ||||||
| 		// We might be an external type, but have empty kind/apiVersion fields. Ensure they are populated before printing. |  | ||||||
| 		if obj.GetObjectKind().GroupVersionKind().Empty() { |  | ||||||
| 			obj = obj.DeepCopyObject() |  | ||||||
| 			obj.GetObjectKind().SetGroupVersionKind(gvks[0]) |  | ||||||
| 		} |  | ||||||
| 		return p.printer.PrintObj(obj, w) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if len(p.versions) == 0 { |  | ||||||
| 		return fmt.Errorf("no version specified, object cannot be converted") |  | ||||||
| 	} |  | ||||||
| 	converted, err := p.converter.ConvertToVersion(obj, schema.GroupVersions(p.versions)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return p.printer.PrintObj(converted, w) |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user
	 Kubernetes Submit Queue
					Kubernetes Submit Queue