From 122e748e18e8c2035cfcfdf49a4207fabe4dd381 Mon Sep 17 00:00:00 2001 From: juanvallejo Date: Tue, 3 Jul 2018 17:50:30 -0400 Subject: [PATCH] fix go-template defaulting for commands w default output format Fixes defaulting done for commands that default to a specific output format (such as yaml, json) when a --template flag is provided and no explicit --output value is given. Under the above case, these commands will now properly default to honoring the --template argument given, and default their --output format to "go-template". --- hack/make-rules/test-cmd-util.sh | 20 ++++++++++++++++---- pkg/kubectl/genericclioptions/print_flags.go | 16 +++++++++++++--- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/hack/make-rules/test-cmd-util.sh b/hack/make-rules/test-cmd-util.sh index 93c0b76714f..1a4deeaa0c7 100755 --- a/hack/make-rules/test-cmd-util.sh +++ b/hack/make-rules/test-cmd-util.sh @@ -1777,10 +1777,6 @@ run_template_output_tests() { output_message=$(kubectl "${kube_flags[@]}" auth reconcile --dry-run -f test/fixtures/pkg/kubectl/cmd/auth/rbac-resource-plus.yaml --template="{{ .metadata.name }}:") kube::test::if_has_string "${output_message}" 'testing-CR:testing-CRB:testing-RB:testing-R:' - # check that "config view" command supports --template output - output_message=$(kubectl "${kube_flags[@]}" config view --output=go-template="{{ .kind }}:") - kube::test::if_has_string "${output_message}" 'Config' - # check that "create clusterrole" command supports --template output output_message=$(kubectl "${kube_flags[@]}" create clusterrole --template="{{ .metadata.name }}:" --verb get myclusterrole --non-resource-url /logs/ --resource pods) kube::test::if_has_string "${output_message}" 'myclusterrole:' @@ -1901,6 +1897,22 @@ EOF output_message=$(kubectl "${kube_flags[@]}" create service nodeport foo --dry-run --tcp=8080 --template="{{ .metadata.name }}:") kube::test::if_has_string "${output_message}" 'foo:' + # check that "config view" ouputs "yaml" as its default output format + output_message=$(kubectl "${kube_flags[@]}" config view) + kube::test::if_has_string "${output_message}" 'kind: Config' + + # check that "config view" command supports --template output + # and that commands that set a default output (yaml in this case), + # default to "go-template" as their output format when a --template + # value is provided, but no explicit --output format is given. + output_message=$(kubectl "${kube_flags[@]}" config view --template="{{ .kind }}:") + kube::test::if_has_string "${output_message}" 'Config' + + # check that running a command with both a --template flag and a + # non-template --output prefers the non-template output value + output_message=$(kubectl "${kube_flags[@]}" create configmap cm --dry-run --template="{{ .metadata.name }}:" --output yaml) + kube::test::if_has_string "${output_message}" 'kind: ConfigMap' + # cleanup kubectl delete cronjob pi "${kube_flags[@]}" kubectl delete pods --all "${kube_flags[@]}" diff --git a/pkg/kubectl/genericclioptions/print_flags.go b/pkg/kubectl/genericclioptions/print_flags.go index 8ed6e22efe9..428d0dff444 100644 --- a/pkg/kubectl/genericclioptions/print_flags.go +++ b/pkg/kubectl/genericclioptions/print_flags.go @@ -22,6 +22,8 @@ import ( "strings" "github.com/spf13/cobra" + "github.com/spf13/pflag" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers" ) @@ -61,7 +63,9 @@ type PrintFlags struct { TypeSetterPrinter *printers.TypeSetterPrinter - OutputFormat *string + OutputFormat *string + outputFlag *pflag.Flag + outputDefaulted bool } func (f *PrintFlags) Complete(successTemplate string) error { @@ -81,8 +85,12 @@ 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 { + // For backwards compatibility we want to support a --template argument given, even when no --output format is provided. + // If a default output format has been set, but no explicit output format has been provided via the --output flag, fallback + // to honoring the --template argument. + if f.TemplatePrinterFlags != nil && f.TemplatePrinterFlags.TemplateArgument != nil && + len(*f.TemplatePrinterFlags.TemplateArgument) > 0 && + (len(outputFormat) == 0 || (f.outputDefaulted && !f.outputFlag.Changed)) { outputFormat = "go-template" } @@ -114,12 +122,14 @@ func (f *PrintFlags) AddFlags(cmd *cobra.Command) { if f.OutputFormat != nil { cmd.Flags().StringVarP(f.OutputFormat, "output", "o", *f.OutputFormat, fmt.Sprintf("Output format. One of: %s.", strings.Join(f.AllowedFormats(), "|"))) + f.outputFlag = cmd.Flag("output") } } // WithDefaultOutput sets a default output format if one is not provided through a flag value func (f *PrintFlags) WithDefaultOutput(output string) *PrintFlags { f.OutputFormat = &output + f.outputDefaulted = true return f }