...

Source file src/k8s.io/kubernetes/cmd/kubeadm/app/util/output/output.go

Documentation: k8s.io/kubernetes/cmd/kubeadm/app/util/output

     1  /*
     2  Copyright 2019 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package output
    18  
    19  import (
    20  	"fmt"
    21  	"io"
    22  	"strings"
    23  
    24  	"github.com/spf13/cobra"
    25  
    26  	"k8s.io/apimachinery/pkg/runtime"
    27  	"k8s.io/cli-runtime/pkg/genericclioptions"
    28  	"k8s.io/cli-runtime/pkg/printers"
    29  )
    30  
    31  const (
    32  	// TextOutput describes the plain text output
    33  	TextOutput = "text"
    34  
    35  	// JSONOutput describes the JSON output
    36  	JSONOutput = "json"
    37  
    38  	// YAMLOutput describes the YAML output
    39  	YAMLOutput = "yaml"
    40  )
    41  
    42  // TextPrintFlags is an interface to handle custom text output
    43  type TextPrintFlags interface {
    44  	ToPrinter(outputFormat string) (Printer, error)
    45  }
    46  
    47  // PrintFlags composes common printer flag structs
    48  // used across kubeadm commands, and provides a method
    49  // of retrieving a known printer based on flag values provided.
    50  type PrintFlags struct {
    51  	// JSONYamlPrintFlags provides default flags necessary for json/yaml printing.
    52  	JSONYamlPrintFlags *genericclioptions.JSONYamlPrintFlags
    53  	// KubeTemplatePrintFlags composes print flags that provide both a JSONPath and a go-template printer.
    54  	KubeTemplatePrintFlags *genericclioptions.KubeTemplatePrintFlags
    55  	// TextPrintFlags provides default flags necessary for kubeadm text printing.
    56  	TextPrintFlags TextPrintFlags
    57  	// TypeSetterPrinter is an implementation of ResourcePrinter that wraps another printer with types set on the objects
    58  	TypeSetterPrinter *printers.TypeSetterPrinter
    59  	// OutputFormat contains currently set output format
    60  	OutputFormat *string
    61  }
    62  
    63  // AllowedFormats returns a list of allowed output formats
    64  func (pf *PrintFlags) AllowedFormats() []string {
    65  	ret := []string{TextOutput}
    66  	ret = append(ret, pf.JSONYamlPrintFlags.AllowedFormats()...)
    67  	ret = append(ret, pf.KubeTemplatePrintFlags.AllowedFormats()...)
    68  
    69  	return ret
    70  }
    71  
    72  // ToPrinter receives an outputFormat and returns a printer capable of
    73  // handling format printing.
    74  // Returns error if the specified outputFormat does not match supported formats.
    75  func (pf *PrintFlags) ToPrinter() (Printer, error) {
    76  	outputFormat := ""
    77  	if pf.OutputFormat != nil {
    78  		outputFormat = *pf.OutputFormat
    79  	}
    80  
    81  	if pf.TextPrintFlags != nil {
    82  		if p, err := pf.TextPrintFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
    83  			return p, err
    84  		}
    85  	}
    86  
    87  	if pf.JSONYamlPrintFlags != nil {
    88  		if p, err := pf.JSONYamlPrintFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
    89  			return NewResourcePrinterWrapper(pf.TypeSetterPrinter.WrapToPrinter(p, err))
    90  		}
    91  	}
    92  
    93  	if pf.KubeTemplatePrintFlags != nil {
    94  		if p, err := pf.KubeTemplatePrintFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
    95  			return NewResourcePrinterWrapper(pf.TypeSetterPrinter.WrapToPrinter(p, err))
    96  		}
    97  	}
    98  
    99  	return nil, genericclioptions.NoCompatiblePrinterError{OutputFormat: pf.OutputFormat, AllowedFormats: pf.AllowedFormats()}
   100  }
   101  
   102  // AddFlags receives a *cobra.Command reference and binds
   103  // flags related to Kubeadm printing to it
   104  func (pf *PrintFlags) AddFlags(cmd *cobra.Command) {
   105  	pf.JSONYamlPrintFlags.AddFlags(cmd)
   106  	pf.KubeTemplatePrintFlags.AddFlags(cmd)
   107  	cmd.Flags().StringVarP(pf.OutputFormat, "experimental-output", "o", *pf.OutputFormat, fmt.Sprintf("Output format. One of: %s.", strings.Join(pf.AllowedFormats(), "|")))
   108  }
   109  
   110  // WithDefaultOutput sets a default output format if one is not provided through a flag value
   111  func (pf *PrintFlags) WithDefaultOutput(outputFormat string) *PrintFlags {
   112  	pf.OutputFormat = &outputFormat
   113  	return pf
   114  }
   115  
   116  // WithTypeSetter sets a wrapper than will surround the returned printer with a printer to type resources
   117  func (pf *PrintFlags) WithTypeSetter(scheme *runtime.Scheme) *PrintFlags {
   118  	pf.TypeSetterPrinter = printers.NewTypeSetter(scheme)
   119  	return pf
   120  }
   121  
   122  // NewOutputFlags creates new KubeadmOutputFlags
   123  func NewOutputFlags(textPrintFlags TextPrintFlags) *PrintFlags {
   124  	outputFormat := ""
   125  
   126  	pf := &PrintFlags{
   127  		OutputFormat: &outputFormat,
   128  
   129  		JSONYamlPrintFlags:     genericclioptions.NewJSONYamlPrintFlags(),
   130  		KubeTemplatePrintFlags: genericclioptions.NewKubeTemplatePrintFlags(),
   131  		TextPrintFlags:         textPrintFlags,
   132  	}
   133  
   134  	// disable deprecated --template option
   135  	pf.KubeTemplatePrintFlags.TemplateArgument = nil
   136  
   137  	return pf
   138  }
   139  
   140  // Printer is a common printing interface in Kubeadm
   141  type Printer interface {
   142  	PrintObj(obj runtime.Object, writer io.Writer) error
   143  	Fprintf(writer io.Writer, format string, args ...interface{}) (n int, err error)
   144  	Fprintln(writer io.Writer, args ...interface{}) (n int, err error)
   145  	Printf(format string, args ...interface{}) (n int, err error)
   146  	Println(args ...interface{}) (n int, err error)
   147  }
   148  
   149  // TextPrinter implements Printer interface for generic text output
   150  type TextPrinter struct {
   151  }
   152  
   153  // PrintObj is an implementation of ResourcePrinter.PrintObj that prints object
   154  func (tp *TextPrinter) PrintObj(obj runtime.Object, writer io.Writer) error {
   155  	_, err := fmt.Fprintf(writer, "%+v\n", obj)
   156  	return err
   157  }
   158  
   159  // Fprintf is a wrapper around fmt.Fprintf
   160  func (tp *TextPrinter) Fprintf(writer io.Writer, format string, args ...interface{}) (n int, err error) {
   161  	return fmt.Fprintf(writer, format, args...)
   162  }
   163  
   164  // Fprintln is a wrapper around fmt.Fprintln
   165  func (tp *TextPrinter) Fprintln(writer io.Writer, args ...interface{}) (n int, err error) {
   166  	return fmt.Fprintln(writer, args...)
   167  }
   168  
   169  // Printf is a wrapper around fmt.Printf
   170  func (tp *TextPrinter) Printf(format string, args ...interface{}) (n int, err error) {
   171  	return fmt.Printf(format, args...)
   172  }
   173  
   174  // Println is a wrapper around fmt.Printf
   175  func (tp *TextPrinter) Println(args ...interface{}) (n int, err error) {
   176  	return fmt.Println(args...)
   177  }
   178  
   179  // ResourcePrinterWrapper wraps ResourcePrinter and implements Printer interface
   180  type ResourcePrinterWrapper struct {
   181  	Printer printers.ResourcePrinter
   182  }
   183  
   184  // NewResourcePrinterWrapper creates new ResourcePrinter object
   185  func NewResourcePrinterWrapper(resourcePrinter printers.ResourcePrinter, err error) (Printer, error) {
   186  	if err != nil {
   187  		return nil, err
   188  	}
   189  	return &ResourcePrinterWrapper{Printer: resourcePrinter}, nil
   190  }
   191  
   192  // PrintObj is an implementation of ResourcePrinter.PrintObj that calls underlying printer API
   193  func (rpw *ResourcePrinterWrapper) PrintObj(obj runtime.Object, writer io.Writer) error {
   194  	return rpw.Printer.PrintObj(obj, writer)
   195  }
   196  
   197  // Fprintf is an empty method to satisfy Printer interface
   198  // and silent info printing for structured output
   199  // This method is usually redefined for the text output
   200  func (rpw *ResourcePrinterWrapper) Fprintf(writer io.Writer, format string, args ...interface{}) (n int, err error) {
   201  	return 0, nil
   202  }
   203  
   204  // Fprintln is an empty method to satisfy the Printer interface
   205  // and silent info printing for structured output
   206  // This method is usually redefined for the text output
   207  func (rpw *ResourcePrinterWrapper) Fprintln(writer io.Writer, args ...interface{}) (n int, err error) {
   208  	return 0, nil
   209  }
   210  
   211  // Printf is an empty method to satisfy Printer interface
   212  // and silent info printing for structured output
   213  // This method is usually redefined for the text output
   214  func (rpw *ResourcePrinterWrapper) Printf(format string, args ...interface{}) (n int, err error) {
   215  	return 0, nil
   216  }
   217  
   218  // Println is an empty method to satisfy Printer interface
   219  // and silent info printing for structured output
   220  // This method is usually redefined for the text output
   221  func (rpw *ResourcePrinterWrapper) Println(args ...interface{}) (n int, err error) {
   222  	return 0, nil
   223  }
   224  

View as plain text