make template printers a recommended printer

This commit is contained in:
David Eads 2018-07-02 10:05:24 -04:00
parent 52d45cfd4f
commit 70417ca150
17 changed files with 70 additions and 144 deletions

View File

@ -18,7 +18,6 @@ go_library(
"create_secret.go",
"create_service.go",
"create_serviceaccount.go",
"flags.go",
],
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/create",
visibility = ["//build/visible_to:pkg_kubectl_cmd_create_CONSUMERS"],
@ -29,7 +28,6 @@ go_library(
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/editor:go_default_library",
"//pkg/kubectl/genericclioptions:go_default_library",
"//pkg/kubectl/genericclioptions/printers:go_default_library",
"//pkg/kubectl/genericclioptions/resource:go_default_library",
"//pkg/kubectl/scheme:go_default_library",
"//pkg/kubectl/util/i18n:go_default_library",

View File

@ -44,7 +44,7 @@ import (
)
type CreateOptions struct {
PrintFlags *PrintFlags
PrintFlags *genericclioptions.PrintFlags
RecordFlags *genericclioptions.RecordFlags
DryRun bool
@ -79,7 +79,7 @@ var (
func NewCreateOptions(ioStreams genericclioptions.IOStreams) *CreateOptions {
return &CreateOptions{
PrintFlags: NewPrintFlags("created", legacyscheme.Scheme),
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(legacyscheme.Scheme),
RecordFlags: genericclioptions.NewRecordFlags(),
Recorder: genericclioptions.NoopRecorder{},
@ -336,7 +336,7 @@ func NameFromCommandArgs(cmd *cobra.Command, args []string) (string, error) {
// CreateSubcommandOptions is an options struct to support create subcommands
type CreateSubcommandOptions struct {
// PrintFlags holds options necessary for obtaining a printer
PrintFlags *PrintFlags
PrintFlags *genericclioptions.PrintFlags
// Name of resource being created
Name string
// StructuredGenerator is the resource generator for the object being created
@ -358,7 +358,7 @@ type CreateSubcommandOptions struct {
func NewCreateSubcommandOptions(ioStreams genericclioptions.IOStreams) *CreateSubcommandOptions {
return &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created", legacyscheme.Scheme),
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(legacyscheme.Scheme),
IOStreams: ioStreams,
}
}

View File

@ -140,7 +140,7 @@ func TestCreateDeploymentNoImage(t *testing.T) {
cmd.Flags().Set("output", "name")
options := &DeploymentOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created", legacyscheme.Scheme),
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(legacyscheme.Scheme),
DryRun: true,
IOStreams: ioStreams,
},

View File

@ -45,7 +45,7 @@ var (
)
type CreateJobOptions struct {
PrintFlags *PrintFlags
PrintFlags *genericclioptions.PrintFlags
PrintObj func(obj runtime.Object) error
@ -64,7 +64,7 @@ type CreateJobOptions struct {
func NewCreateJobOptions(ioStreams genericclioptions.IOStreams) *CreateJobOptions {
return &CreateJobOptions{
PrintFlags: NewPrintFlags("created", legacyscheme.Scheme),
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(legacyscheme.Scheme),
IOStreams: ioStreams,
}
}

View File

@ -85,7 +85,7 @@ func TestCreateJobFromCronJob(t *testing.T) {
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
printFlags := NewPrintFlags("created", legacyscheme.Scheme)
printFlags := genericclioptions.NewPrintFlags("created").WithTypeSetter(legacyscheme.Scheme)
ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmdOptions := &CreateJobOptions{

View File

@ -58,7 +58,7 @@ func TestCreatePdb(t *testing.T) {
cmd.Flags().Set("dry-run", "true")
cmd.Flags().Set("output", outputFormat)
printFlags := NewPrintFlags("created", legacyscheme.Scheme)
printFlags := genericclioptions.NewPrintFlags("created").WithTypeSetter(legacyscheme.Scheme)
printFlags.OutputFormat = &outputFormat
options := &PodDisruptionBudgetOpts{

View File

@ -59,7 +59,7 @@ func TestCreatePriorityClass(t *testing.T) {
cmd.Flags().Set("dry-run", "true")
cmd.Flags().Set("output", outputFormat)
printFlags := NewPrintFlags("created", legacyscheme.Scheme)
printFlags := genericclioptions.NewPrintFlags("created").WithTypeSetter(legacyscheme.Scheme)
printFlags.OutputFormat = &outputFormat
options := &PriorityClassOpts{

View File

@ -112,7 +112,7 @@ type ResourceOptions struct {
}
type CreateRoleOptions struct {
PrintFlags *PrintFlags
PrintFlags *genericclioptions.PrintFlags
Name string
Verbs []string
@ -131,7 +131,7 @@ type CreateRoleOptions struct {
func NewCreateRoleOptions(ioStreams genericclioptions.IOStreams) *CreateRoleOptions {
return &CreateRoleOptions{
PrintFlags: NewPrintFlags("created", legacyscheme.Scheme),
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(legacyscheme.Scheme),
IOStreams: ioStreams,
}

View File

@ -372,14 +372,14 @@ func TestComplete(t *testing.T) {
"test-missing-name": {
params: []string{},
roleOptions: &CreateRoleOptions{
PrintFlags: NewPrintFlags("created", legacyscheme.Scheme),
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(legacyscheme.Scheme),
},
expectErr: true,
},
"test-duplicate-verbs": {
params: []string{roleName},
roleOptions: &CreateRoleOptions{
PrintFlags: NewPrintFlags("created", legacyscheme.Scheme),
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(legacyscheme.Scheme),
Name: roleName,
Verbs: []string{
"get",
@ -412,7 +412,7 @@ func TestComplete(t *testing.T) {
"test-verball": {
params: []string{roleName},
roleOptions: &CreateRoleOptions{
PrintFlags: NewPrintFlags("created", legacyscheme.Scheme),
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(legacyscheme.Scheme),
Name: roleName,
Verbs: []string{
"get",
@ -441,7 +441,7 @@ func TestComplete(t *testing.T) {
"test-duplicate-resourcenames": {
params: []string{roleName},
roleOptions: &CreateRoleOptions{
PrintFlags: NewPrintFlags("created", legacyscheme.Scheme),
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(legacyscheme.Scheme),
Name: roleName,
Verbs: []string{"*"},
ResourceNames: []string{"foo", "foo"},
@ -466,7 +466,7 @@ func TestComplete(t *testing.T) {
"test-valid-complete-case": {
params: []string{roleName},
roleOptions: &CreateRoleOptions{
PrintFlags: NewPrintFlags("created", legacyscheme.Scheme),
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(legacyscheme.Scheme),
Name: roleName,
Verbs: []string{"*"},
ResourceNames: []string{"foo"},

View File

@ -1,93 +0,0 @@
/*
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 create
import (
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/apimachinery/pkg/runtime"
genericprinters "k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers"
"k8s.io/kubernetes/pkg/printers"
)
// PrintFlags composes common printer flag structs
// used across all create commands, and provides a method
// of retrieving a known printer based on flag values provided.
type PrintFlags struct {
JSONYamlPrintFlags *genericclioptions.JSONYamlPrintFlags
NamePrintFlags *genericclioptions.NamePrintFlags
TemplateFlags *genericclioptions.KubeTemplatePrintFlags
TypeSetter *genericprinters.TypeSetterPrinter
OutputFormat *string
}
func (f *PrintFlags) AllowedFormats() []string {
return append(append(f.JSONYamlPrintFlags.AllowedFormats(), f.NamePrintFlags.AllowedFormats()...),
f.TemplateFlags.AllowedFormats()...)
}
func (f *PrintFlags) Complete(successTemplate string) error {
return f.NamePrintFlags.Complete(successTemplate)
}
func (f *PrintFlags) ToPrinter() (printers.ResourcePrinter, error) {
outputFormat := ""
if f.OutputFormat != nil {
outputFormat = *f.OutputFormat
}
if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
return f.TypeSetter.WrapToPrinter(p, err)
}
if p, err := f.NamePrintFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
return f.TypeSetter.WrapToPrinter(p, err)
}
if p, err := f.TemplateFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
return f.TypeSetter.WrapToPrinter(p, err)
}
return nil, genericclioptions.NoCompatiblePrinterError{OutputFormat: &outputFormat, AllowedFormats: f.AllowedFormats()}
}
func (f *PrintFlags) AddFlags(cmd *cobra.Command) {
f.JSONYamlPrintFlags.AddFlags(cmd)
f.NamePrintFlags.AddFlags(cmd)
f.TemplateFlags.AddFlags(cmd)
if f.OutputFormat != nil {
cmd.Flags().StringVarP(f.OutputFormat, "output", "o", *f.OutputFormat, "Output format. One of: json|yaml|wide|name|custom-columns=...|custom-columns-file=...|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=... See custom columns [http://kubernetes.io/docs/user-guide/kubectl-overview/#custom-columns], golang template [http://golang.org/pkg/text/template/#pkg-overview] and jsonpath template [http://kubernetes.io/docs/user-guide/jsonpath].")
}
}
func NewPrintFlags(operation string, scheme runtime.ObjectTyper) *PrintFlags {
outputFormat := ""
return &PrintFlags{
OutputFormat: &outputFormat,
JSONYamlPrintFlags: genericclioptions.NewJSONYamlPrintFlags(),
NamePrintFlags: genericclioptions.NewNamePrintFlags(operation),
TemplateFlags: genericclioptions.NewKubeTemplatePrintFlags(),
TypeSetter: genericprinters.NewTypeSetter(scheme),
}
}

View File

@ -89,15 +89,8 @@ type ReplaceOptions struct {
}
func NewReplaceOptions(streams genericclioptions.IOStreams) *ReplaceOptions {
outputFormat := ""
return &ReplaceOptions{
// TODO(juanvallejo): figure out why we only support the "name" outputFormat in this command
// we only support "-o name" for this command, so only register the name printer
PrintFlags: &genericclioptions.PrintFlags{
OutputFormat: &outputFormat,
NamePrintFlags: genericclioptions.NewNamePrintFlags("replaced"),
},
PrintFlags: genericclioptions.NewPrintFlags("replaced"),
DeleteFlags: NewDeleteFlags("to use to replace the resource."),
IOStreams: streams,

View File

@ -93,15 +93,8 @@ type ScaleOptions struct {
}
func NewScaleOptions(ioStreams genericclioptions.IOStreams) *ScaleOptions {
outputFormat := ""
return &ScaleOptions{
// TODO(juanvallejo): figure out why we only support the "name" outputFormat in this command
// we only support "-o name" for this command, so only register the name printer
PrintFlags: &genericclioptions.PrintFlags{
OutputFormat: &outputFormat,
NamePrintFlags: genericclioptions.NewNamePrintFlags("scaled"),
},
PrintFlags: genericclioptions.NewPrintFlags("scaled"),
RecordFlags: genericclioptions.NewRecordFlags(),
CurrentReplicas: -1,
Recorder: genericclioptions.NoopRecorder{},

View File

@ -11,9 +11,12 @@ go_library(
"filename_flags.go",
"io_options.go",
"json_yaml_flags.go",
"jsonpath_flags.go",
"kube_template_flags.go",
"name_flags.go",
"print_flags.go",
"record_flags.go",
"template_flags.go",
],
importpath = "k8s.io/kubernetes/pkg/kubectl/genericclioptions",
visibility = ["//visibility:public"],
@ -57,7 +60,9 @@ go_test(
name = "go_default_test",
srcs = [
"json_yaml_flags_test.go",
"jsonpath_flags_test.go",
"name_flags_test.go",
"template_flags_test.go",
],
embed = [":go_default_library"],
deps = [

View File

@ -26,18 +26,25 @@ import (
// This is necessary if dealing with cases that require support both both printers, since both sets of flags
// require overlapping flags.
type KubeTemplatePrintFlags struct {
*GoTemplatePrintFlags
*JSONPathPrintFlags
GoTemplatePrintFlags *GoTemplatePrintFlags
JSONPathPrintFlags *JSONPathPrintFlags
AllowMissingKeys *bool
TemplateArgument *string
}
func (f *KubeTemplatePrintFlags) AllowedFormats() []string {
if f == nil {
return []string{}
}
return append(f.GoTemplatePrintFlags.AllowedFormats(), f.JSONPathPrintFlags.AllowedFormats()...)
}
func (f *KubeTemplatePrintFlags) ToPrinter(outputFormat string) (printers.ResourcePrinter, error) {
if f == nil {
return nil, NoCompatiblePrinterError{}
}
if p, err := f.JSONPathPrintFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) {
return p, err
}
@ -47,6 +54,10 @@ func (f *KubeTemplatePrintFlags) ToPrinter(outputFormat string) (printers.Resour
// AddFlags receives a *cobra.Command reference and binds
// flags related to template printing to it
func (f *KubeTemplatePrintFlags) AddFlags(c *cobra.Command) {
if f == nil {
return
}
if f.TemplateArgument != nil {
c.Flags().StringVar(f.TemplateArgument, "template", *f.TemplateArgument, "Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].")
c.MarkFlagFilename("template")

View File

@ -55,8 +55,9 @@ func IsNoCompatiblePrinterError(err error) bool {
// used across all commands, and provides a method
// of retrieving a known printer based on flag values provided.
type PrintFlags struct {
JSONYamlPrintFlags *JSONYamlPrintFlags
NamePrintFlags *NamePrintFlags
JSONYamlPrintFlags *JSONYamlPrintFlags
NamePrintFlags *NamePrintFlags
TemplatePrinterFlags *KubeTemplatePrintFlags
TypeSetterPrinter *printers.TypeSetterPrinter
@ -68,7 +69,11 @@ func (f *PrintFlags) Complete(successTemplate string) error {
}
func (f *PrintFlags) AllowedFormats() []string {
return append(f.JSONYamlPrintFlags.AllowedFormats(), f.NamePrintFlags.AllowedFormats()...)
ret := []string{}
ret = append(ret, f.JSONYamlPrintFlags.AllowedFormats()...)
ret = append(ret, f.NamePrintFlags.AllowedFormats()...)
ret = append(ret, f.TemplatePrinterFlags.AllowedFormats()...)
return ret
}
func (f *PrintFlags) ToPrinter() (printers.ResourcePrinter, error) {
@ -76,6 +81,10 @@ func (f *PrintFlags) ToPrinter() (printers.ResourcePrinter, error) {
if f.OutputFormat != nil {
outputFormat = *f.OutputFormat
}
// for backwards compatibility we want to support a --template argument given, even when no --output format is provided
if f.TemplatePrinterFlags != nil && f.TemplatePrinterFlags.TemplateArgument != nil && len(*f.TemplatePrinterFlags.TemplateArgument) > 0 && len(outputFormat) == 0 {
outputFormat = "go-template"
}
if f.JSONYamlPrintFlags != nil {
if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) {
@ -89,12 +98,19 @@ func (f *PrintFlags) ToPrinter() (printers.ResourcePrinter, error) {
}
}
if f.TemplatePrinterFlags != nil {
if p, err := f.TemplatePrinterFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) {
return f.TypeSetterPrinter.WrapToPrinter(p, err)
}
}
return nil, NoCompatiblePrinterError{OutputFormat: f.OutputFormat, AllowedFormats: f.AllowedFormats()}
}
func (f *PrintFlags) AddFlags(cmd *cobra.Command) {
f.JSONYamlPrintFlags.AddFlags(cmd)
f.NamePrintFlags.AddFlags(cmd)
f.TemplatePrinterFlags.AddFlags(cmd)
if f.OutputFormat != nil {
cmd.Flags().StringVarP(f.OutputFormat, "output", "o", *f.OutputFormat, fmt.Sprintf("Output format. One of: %s.", strings.Join(f.AllowedFormats(), "|")))
@ -119,7 +135,8 @@ func NewPrintFlags(operation string) *PrintFlags {
return &PrintFlags{
OutputFormat: &outputFormat,
JSONYamlPrintFlags: NewJSONYamlPrintFlags(),
NamePrintFlags: NewNamePrintFlags(operation),
JSONYamlPrintFlags: NewJSONYamlPrintFlags(),
NamePrintFlags: NewNamePrintFlags(operation),
TemplatePrinterFlags: NewKubeTemplatePrintFlags(),
}
}

View File

@ -6,8 +6,10 @@ go_library(
"discard.go",
"interface.go",
"json.go",
"jsonpath.go",
"name.go",
"sourcechecker.go",
"template.go",
"typesetter.go",
],
importpath = "k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers",
@ -17,14 +19,22 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/client-go/util/jsonpath:go_default_library",
"//vendor/github.com/ghodss/yaml:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["sourcechecker_test.go"],
srcs = [
"sourcechecker_test.go",
"template_test.go",
],
embed = [":go_default_library"],
deps = [
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
],
)
filegroup(

View File

@ -13,12 +13,7 @@ go_library(
"customcolumn_flags.go",
"humanreadable.go",
"interface.go",
"jsonpath.go",
"jsonpath_flags.go",
"kube_template_flags.go",
"tabwriter.go",
"template.go",
"template_flags.go",
],
importpath = "k8s.io/kubernetes/pkg/printers",
deps = [
@ -61,9 +56,6 @@ go_test(
"customcolumn_flags_test.go",
"customcolumn_test.go",
"humanreadable_test.go",
"jsonpath_flags_test.go",
"template_flags_test.go",
"template_test.go",
],
embed = [":go_default_library"],
deps = [