mirror of https://github.com/k3s-io/k3s
188 lines
6.3 KiB
Go
188 lines
6.3 KiB
Go
|
/*
|
||
|
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 get
|
||
|
|
||
|
import (
|
||
|
"strings"
|
||
|
|
||
|
"github.com/spf13/cobra"
|
||
|
|
||
|
"k8s.io/apimachinery/pkg/api/meta"
|
||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||
|
"k8s.io/cli-runtime/pkg/printers"
|
||
|
"k8s.io/kubectl/pkg/util/openapi"
|
||
|
)
|
||
|
|
||
|
// PrintFlags composes common printer flag structs
|
||
|
// used in the Get command.
|
||
|
type PrintFlags struct {
|
||
|
JSONYamlPrintFlags *genericclioptions.JSONYamlPrintFlags
|
||
|
NamePrintFlags *genericclioptions.NamePrintFlags
|
||
|
CustomColumnsFlags *CustomColumnsPrintFlags
|
||
|
HumanReadableFlags *HumanPrintFlags
|
||
|
TemplateFlags *genericclioptions.KubeTemplatePrintFlags
|
||
|
|
||
|
NoHeaders *bool
|
||
|
OutputFormat *string
|
||
|
}
|
||
|
|
||
|
// SetKind sets the Kind option of humanreadable flags
|
||
|
func (f *PrintFlags) SetKind(kind schema.GroupKind) {
|
||
|
f.HumanReadableFlags.SetKind(kind)
|
||
|
}
|
||
|
|
||
|
// EnsureWithNamespace ensures that humanreadable flags return
|
||
|
// a printer capable of printing with a "namespace" column.
|
||
|
func (f *PrintFlags) EnsureWithNamespace() error {
|
||
|
return f.HumanReadableFlags.EnsureWithNamespace()
|
||
|
}
|
||
|
|
||
|
// EnsureWithKind ensures that humanreadable flags return
|
||
|
// a printer capable of including resource kinds.
|
||
|
func (f *PrintFlags) EnsureWithKind() error {
|
||
|
return f.HumanReadableFlags.EnsureWithKind()
|
||
|
}
|
||
|
|
||
|
// Copy returns a copy of PrintFlags for mutation
|
||
|
func (f *PrintFlags) Copy() PrintFlags {
|
||
|
printFlags := *f
|
||
|
return printFlags
|
||
|
}
|
||
|
|
||
|
// AllowedFormats is the list of formats in which data can be displayed
|
||
|
func (f *PrintFlags) AllowedFormats() []string {
|
||
|
formats := f.JSONYamlPrintFlags.AllowedFormats()
|
||
|
formats = append(formats, f.NamePrintFlags.AllowedFormats()...)
|
||
|
formats = append(formats, f.TemplateFlags.AllowedFormats()...)
|
||
|
formats = append(formats, f.CustomColumnsFlags.AllowedFormats()...)
|
||
|
formats = append(formats, f.HumanReadableFlags.AllowedFormats()...)
|
||
|
return formats
|
||
|
}
|
||
|
|
||
|
// UseOpenAPIColumns modifies the output format, as well as the
|
||
|
// "allowMissingKeys" option for template printers, to values
|
||
|
// defined in the OpenAPI schema of a resource.
|
||
|
func (f *PrintFlags) UseOpenAPIColumns(api openapi.Resources, mapping *meta.RESTMapping) error {
|
||
|
// Found openapi metadata for this resource
|
||
|
schema := api.LookupResource(mapping.GroupVersionKind)
|
||
|
if schema == nil {
|
||
|
// Schema not found, return empty columns
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
columns, found := openapi.GetPrintColumns(schema.GetExtensions())
|
||
|
if !found {
|
||
|
// Extension not found, return empty columns
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
parts := strings.SplitN(columns, "=", 2)
|
||
|
if len(parts) < 2 {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
allowMissingKeys := true
|
||
|
f.OutputFormat = &parts[0]
|
||
|
f.TemplateFlags.TemplateArgument = &parts[1]
|
||
|
f.TemplateFlags.AllowMissingKeys = &allowMissingKeys
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// ToPrinter attempts to find a composed set of PrintFlags suitable for
|
||
|
// returning a printer based on current flag values.
|
||
|
func (f *PrintFlags) ToPrinter() (printers.ResourcePrinter, error) {
|
||
|
outputFormat := ""
|
||
|
if f.OutputFormat != nil {
|
||
|
outputFormat = *f.OutputFormat
|
||
|
}
|
||
|
|
||
|
noHeaders := false
|
||
|
if f.NoHeaders != nil {
|
||
|
noHeaders = *f.NoHeaders
|
||
|
}
|
||
|
f.HumanReadableFlags.NoHeaders = noHeaders
|
||
|
f.CustomColumnsFlags.NoHeaders = noHeaders
|
||
|
|
||
|
// for "get.go" we want to support a --template argument given, even when no --output format is provided
|
||
|
if f.TemplateFlags.TemplateArgument != nil && len(*f.TemplateFlags.TemplateArgument) > 0 && len(outputFormat) == 0 {
|
||
|
outputFormat = "go-template"
|
||
|
}
|
||
|
|
||
|
if p, err := f.TemplateFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
|
||
|
return p, err
|
||
|
}
|
||
|
|
||
|
if f.TemplateFlags.TemplateArgument != nil {
|
||
|
f.CustomColumnsFlags.TemplateArgument = *f.TemplateFlags.TemplateArgument
|
||
|
}
|
||
|
|
||
|
if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
|
||
|
return p, err
|
||
|
}
|
||
|
|
||
|
if p, err := f.HumanReadableFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
|
||
|
return p, err
|
||
|
}
|
||
|
|
||
|
if p, err := f.CustomColumnsFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
|
||
|
return p, err
|
||
|
}
|
||
|
|
||
|
if p, err := f.NamePrintFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
|
||
|
return p, err
|
||
|
}
|
||
|
|
||
|
return nil, genericclioptions.NoCompatiblePrinterError{OutputFormat: &outputFormat, AllowedFormats: f.AllowedFormats()}
|
||
|
}
|
||
|
|
||
|
// AddFlags receives a *cobra.Command reference and binds
|
||
|
// flags related to humanreadable and template printing.
|
||
|
func (f *PrintFlags) AddFlags(cmd *cobra.Command) {
|
||
|
f.JSONYamlPrintFlags.AddFlags(cmd)
|
||
|
f.NamePrintFlags.AddFlags(cmd)
|
||
|
f.TemplateFlags.AddFlags(cmd)
|
||
|
f.HumanReadableFlags.AddFlags(cmd)
|
||
|
f.CustomColumnsFlags.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].")
|
||
|
}
|
||
|
if f.NoHeaders != nil {
|
||
|
cmd.Flags().BoolVar(f.NoHeaders, "no-headers", *f.NoHeaders, "When using the default or custom-column output format, don't print headers (default print headers).")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// NewGetPrintFlags returns flags associated with humanreadable,
|
||
|
// template, and "name" printing, with default values set.
|
||
|
func NewGetPrintFlags() *PrintFlags {
|
||
|
outputFormat := ""
|
||
|
noHeaders := false
|
||
|
|
||
|
return &PrintFlags{
|
||
|
OutputFormat: &outputFormat,
|
||
|
NoHeaders: &noHeaders,
|
||
|
|
||
|
JSONYamlPrintFlags: genericclioptions.NewJSONYamlPrintFlags(),
|
||
|
NamePrintFlags: genericclioptions.NewNamePrintFlags(""),
|
||
|
TemplateFlags: genericclioptions.NewKubeTemplatePrintFlags(),
|
||
|
|
||
|
HumanReadableFlags: NewHumanPrintFlags(),
|
||
|
CustomColumnsFlags: NewCustomColumnsPrintFlags(),
|
||
|
}
|
||
|
}
|