printing.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. Copyright 2014 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package util
  14. import (
  15. "fmt"
  16. "io"
  17. "strings"
  18. "k8s.io/kubernetes/pkg/api/meta"
  19. "k8s.io/kubernetes/pkg/api/unversioned"
  20. "k8s.io/kubernetes/pkg/kubectl"
  21. "github.com/spf13/cobra"
  22. )
  23. // AddPrinterFlags adds printing related flags to a command (e.g. output format, no headers, template path)
  24. func AddPrinterFlags(cmd *cobra.Command) {
  25. AddOutputFlags(cmd)
  26. cmd.Flags().String("output-version", "", "Output the formatted object with the given group version (for ex: 'extensions/v1beta1').")
  27. AddNoHeadersFlags(cmd)
  28. cmd.Flags().Bool("show-labels", false, "When printing, show all labels as the last column (default hide labels column)")
  29. cmd.Flags().String("template", "", "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].")
  30. cmd.MarkFlagFilename("template")
  31. cmd.Flags().String("sort-by", "", "If non-empty, sort list types using this field specification. The field specification is expressed as a JSONPath expression (e.g. '{.metadata.name}'). The field in the API resource specified by this JSONPath expression must be an integer or a string.")
  32. cmd.Flags().BoolP("show-all", "a", false, "When printing, show all resources (default hide terminated pods.)")
  33. }
  34. // AddOutputFlagsForMutation adds output related flags to a command. Used by mutations only.
  35. func AddOutputFlagsForMutation(cmd *cobra.Command) {
  36. cmd.Flags().StringP("output", "o", "", "Output mode. Use \"-o name\" for shorter output (resource/name).")
  37. }
  38. // AddOutputFlags adds output related flags to a command.
  39. func AddOutputFlags(cmd *cobra.Command) {
  40. cmd.Flags().StringP("output", "o", "", "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].")
  41. }
  42. // AddNoHeadersFlags adds no-headers flags to a command.
  43. func AddNoHeadersFlags(cmd *cobra.Command) {
  44. cmd.Flags().Bool("no-headers", false, "When using the default or custom-column output format, don't print headers.")
  45. }
  46. // PrintSuccess prints message after finishing mutating operations
  47. func PrintSuccess(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resource string, name string, operation string) {
  48. resource, _ = mapper.ResourceSingularizer(resource)
  49. if shortOutput {
  50. // -o name: prints resource/name
  51. if len(resource) > 0 {
  52. fmt.Fprintf(out, "%s/%s\n", resource, name)
  53. } else {
  54. fmt.Fprintf(out, "%s\n", name)
  55. }
  56. } else {
  57. // understandable output by default
  58. if len(resource) > 0 {
  59. fmt.Fprintf(out, "%s \"%s\" %s\n", resource, name, operation)
  60. } else {
  61. fmt.Fprintf(out, "\"%s\" %s\n", name, operation)
  62. }
  63. }
  64. }
  65. // ValidateOutputArgs validates -o flag args for mutations
  66. func ValidateOutputArgs(cmd *cobra.Command) error {
  67. outputMode := GetFlagString(cmd, "output")
  68. if outputMode != "" && outputMode != "name" {
  69. return UsageError(cmd, "Unexpected -o output mode: %v. We only support '-o name'.", outputMode)
  70. }
  71. return nil
  72. }
  73. // OutputVersion returns the preferred output version for generic content (JSON, YAML, or templates)
  74. // defaultVersion is never mutated. Nil simply allows clean passing in common usage from client.Config
  75. func OutputVersion(cmd *cobra.Command, defaultVersion *unversioned.GroupVersion) (unversioned.GroupVersion, error) {
  76. outputVersionString := GetFlagString(cmd, "output-version")
  77. if len(outputVersionString) == 0 {
  78. if defaultVersion == nil {
  79. return unversioned.GroupVersion{}, nil
  80. }
  81. return *defaultVersion, nil
  82. }
  83. return unversioned.ParseGroupVersion(outputVersionString)
  84. }
  85. // PrinterForCommand returns the default printer for this command.
  86. // Requires that printer flags have been added to cmd (see AddPrinterFlags).
  87. func PrinterForCommand(cmd *cobra.Command) (kubectl.ResourcePrinter, bool, error) {
  88. outputFormat := GetFlagString(cmd, "output")
  89. // templates are logically optional for specifying a format.
  90. // TODO once https://github.com/kubernetes/kubernetes/issues/12668 is fixed, this should fall back to GetFlagString
  91. templateFile, _ := cmd.Flags().GetString("template")
  92. if len(outputFormat) == 0 && len(templateFile) != 0 {
  93. outputFormat = "template"
  94. }
  95. templateFormat := []string{
  96. "go-template=", "go-template-file=", "jsonpath=", "jsonpath-file=", "custom-columns=", "custom-columns-file=",
  97. }
  98. for _, format := range templateFormat {
  99. if strings.HasPrefix(outputFormat, format) {
  100. templateFile = outputFormat[len(format):]
  101. outputFormat = format[:len(format)-1]
  102. }
  103. }
  104. printer, generic, err := kubectl.GetPrinter(outputFormat, templateFile, GetFlagBool(cmd, "no-headers"))
  105. if err != nil {
  106. return nil, generic, err
  107. }
  108. return maybeWrapSortingPrinter(cmd, printer), generic, nil
  109. }
  110. func maybeWrapSortingPrinter(cmd *cobra.Command, printer kubectl.ResourcePrinter) kubectl.ResourcePrinter {
  111. sorting, err := cmd.Flags().GetString("sort-by")
  112. if err != nil {
  113. // error can happen on missing flag or bad flag type. In either case, this command didn't intent to sort
  114. return printer
  115. }
  116. if len(sorting) != 0 {
  117. return &kubectl.SortingPrinter{
  118. Delegate: printer,
  119. SortField: fmt.Sprintf("{%s}", sorting),
  120. }
  121. }
  122. return printer
  123. }