Merge pull request #114972 from seans3/remove-openapi-printing

Removes deprecated kubectl openapi column printing
This commit is contained in:
Kubernetes Prow Robot 2023-01-11 00:53:45 -08:00 committed by GitHub
commit cfa6ad50e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 1 additions and 160 deletions

View File

@ -57,7 +57,6 @@ type GetOptions struct {
PrintFlags *PrintFlags PrintFlags *PrintFlags
ToPrinter func(*meta.RESTMapping, *bool, bool, bool) (printers.ResourcePrinterFunc, error) ToPrinter func(*meta.RESTMapping, *bool, bool, bool) (printers.ResourcePrinterFunc, error)
IsHumanReadablePrinter bool IsHumanReadablePrinter bool
PrintWithOpenAPICols bool
CmdParent string CmdParent string
@ -137,7 +136,6 @@ var (
) )
const ( const (
useOpenAPIPrintColumnFlagLabel = "use-openapi-print-columns"
useServerPrintColumns = "server-print" useServerPrintColumns = "server-print"
) )
@ -184,7 +182,6 @@ func NewCmdGet(parent string, f cmdutil.Factory, streams genericclioptions.IOStr
cmd.Flags().BoolVar(&o.IgnoreNotFound, "ignore-not-found", o.IgnoreNotFound, "If the requested object does not exist the command will return exit code 0.") cmd.Flags().BoolVar(&o.IgnoreNotFound, "ignore-not-found", o.IgnoreNotFound, "If the requested object does not exist the command will return exit code 0.")
cmd.Flags().StringVar(&o.FieldSelector, "field-selector", o.FieldSelector, "Selector (field query) to filter on, supports '=', '==', and '!='.(e.g. --field-selector key1=value1,key2=value2). The server only supports a limited number of field queries per type.") cmd.Flags().StringVar(&o.FieldSelector, "field-selector", o.FieldSelector, "Selector (field query) to filter on, supports '=', '==', and '!='.(e.g. --field-selector key1=value1,key2=value2). The server only supports a limited number of field queries per type.")
cmd.Flags().BoolVarP(&o.AllNamespaces, "all-namespaces", "A", o.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.") cmd.Flags().BoolVarP(&o.AllNamespaces, "all-namespaces", "A", o.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")
addOpenAPIPrintColumnFlags(cmd, o)
addServerPrintColumnFlags(cmd, o) addServerPrintColumnFlags(cmd, o)
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "identifying the resource to get from a server.") cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "identifying the resource to get from a server.")
cmdutil.AddChunkSizeFlag(cmd, &o.ChunkSize) cmdutil.AddChunkSizeFlag(cmd, &o.ChunkSize)
@ -241,11 +238,6 @@ func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
printFlags := o.PrintFlags.Copy() printFlags := o.PrintFlags.Copy()
if mapping != nil { if mapping != nil {
if !cmdSpecifiesOutputFmt(cmd) && o.PrintWithOpenAPICols {
if apiSchema, err := f.OpenAPISchema(); err == nil {
printFlags.UseOpenAPIColumns(apiSchema, mapping)
}
}
printFlags.SetKind(mapping.GroupVersionKind.GroupKind()) printFlags.SetKind(mapping.GroupVersionKind.GroupKind())
} }
if withNamespace { if withNamespace {
@ -294,11 +286,6 @@ func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
} }
} }
// openapi printing is mutually exclusive with server side printing
if o.PrintWithOpenAPICols && o.ServerPrint {
fmt.Fprintf(o.IOStreams.ErrOut, "warning: --%s requested, --%s will be ignored\n", useOpenAPIPrintColumnFlagLabel, useServerPrintColumns)
}
return nil return nil
} }
@ -433,10 +420,6 @@ func NewRuntimeSorter(objects []runtime.Object, sortBy string) *RuntimeSorter {
} }
func (o *GetOptions) transformRequests(req *rest.Request) { func (o *GetOptions) transformRequests(req *rest.Request) {
// We need full objects if printing with openapi columns
if o.PrintWithOpenAPICols {
return
}
if !o.ServerPrint || !o.IsHumanReadablePrinter { if !o.ServerPrint || !o.IsHumanReadablePrinter {
return return
} }
@ -580,13 +563,6 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
lastMapping = mapping lastMapping = mapping
} }
// ensure a versioned object is passed to the custom-columns printer
// if we are using OpenAPI columns to print
if o.PrintWithOpenAPICols {
printer.PrintObj(info.Object, w)
continue
}
printer.PrintObj(info.Object, w) printer.PrintObj(info.Object, w)
} }
w.Flush() w.Flush()
@ -830,11 +806,6 @@ func (o *GetOptions) printGeneric(r *resource.Result) error {
return utilerrors.Reduce(utilerrors.Flatten(utilerrors.NewAggregate(errs))) return utilerrors.Reduce(utilerrors.Flatten(utilerrors.NewAggregate(errs)))
} }
func addOpenAPIPrintColumnFlags(cmd *cobra.Command, opt *GetOptions) {
cmd.Flags().BoolVar(&opt.PrintWithOpenAPICols, useOpenAPIPrintColumnFlagLabel, opt.PrintWithOpenAPICols, "If true, use x-kubernetes-print-column metadata (if present) from the OpenAPI schema for displaying a resource.")
cmd.Flags().MarkDeprecated(useOpenAPIPrintColumnFlagLabel, "deprecated in favor of server-side printing")
}
func addServerPrintColumnFlags(cmd *cobra.Command, opt *GetOptions) { func addServerPrintColumnFlags(cmd *cobra.Command, opt *GetOptions) {
cmd.Flags().BoolVar(&opt.ServerPrint, useServerPrintColumns, opt.ServerPrint, "If true, have the server return the appropriate table output. Supports extension APIs and CRDs.") cmd.Flags().BoolVar(&opt.ServerPrint, useServerPrintColumns, opt.ServerPrint, "If true, have the server return the appropriate table output. Supports extension APIs and CRDs.")
} }
@ -843,10 +814,6 @@ func shouldGetNewPrinterForMapping(printer printers.ResourcePrinter, lastMapping
return printer == nil || lastMapping == nil || mapping == nil || mapping.Resource != lastMapping.Resource return printer == nil || lastMapping == nil || mapping == nil || mapping.Resource != lastMapping.Resource
} }
func cmdSpecifiesOutputFmt(cmd *cobra.Command) bool {
return cmdutil.GetFlagString(cmd, "output") != ""
}
func multipleGVKsRequested(infos []*resource.Info) bool { func multipleGVKsRequested(infos []*resource.Info) bool {
if len(infos) < 2 { if len(infos) < 2 {
return false return false

View File

@ -22,12 +22,10 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/printers" "k8s.io/cli-runtime/pkg/printers"
"k8s.io/kubectl/pkg/cmd/util" "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/openapi"
) )
// PrintFlags composes common printer flag structs // PrintFlags composes common printer flag structs
@ -76,35 +74,6 @@ func (f *PrintFlags) AllowedFormats() []string {
return formats 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 // ToPrinter attempts to find a composed set of PrintFlags suitable for
// returning a printer based on current flag values. // returning a printer based on current flag values.
func (f *PrintFlags) ToPrinter() (printers.ResourcePrinter, error) { func (f *PrintFlags) ToPrinter() (printers.ResourcePrinter, error) {

View File

@ -22,7 +22,6 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"path/filepath"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
@ -36,7 +35,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/streaming" "k8s.io/apimachinery/pkg/runtime/serializer/streaming"
"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
@ -45,11 +43,8 @@ import (
restclient "k8s.io/client-go/rest" restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
restclientwatch "k8s.io/client-go/rest/watch" restclientwatch "k8s.io/client-go/rest/watch"
"k8s.io/kube-openapi/pkg/util/proto"
cmdtesting "k8s.io/kubectl/pkg/cmd/testing" cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
"k8s.io/kubectl/pkg/scheme" "k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util/openapi"
openapitesting "k8s.io/kubectl/pkg/util/openapi/testing"
) )
var ( var (
@ -87,11 +82,9 @@ func testComponentStatusData() *corev1.ComponentStatusList {
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get. // Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
func TestGetUnknownSchemaObject(t *testing.T) { func TestGetUnknownSchemaObject(t *testing.T) {
t.Skip("This test is completely broken. The first thing it does is add the object to the scheme!") t.Skip("This test is completely broken. The first thing it does is add the object to the scheme!")
var openapiSchemaPath = filepath.Join("..", "..", "..", "testdata", "openapi", "swagger.json")
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
_, _, codec := cmdtesting.NewExternalScheme() _, _, codec := cmdtesting.NewExternalScheme()
tf.OpenAPISchemaFunc = openapitesting.CreateOpenAPISchemaFunc(openapiSchemaPath)
obj := &cmdtesting.ExternalType{ obj := &cmdtesting.ExternalType{
Kind: "Type", Kind: "Type",
@ -161,67 +154,6 @@ func TestGetSchemaObject(t *testing.T) {
} }
} }
func TestGetObjectsWithOpenAPIOutputFormatPresent(t *testing.T) {
pods, _, _ := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
// override the openAPISchema function to return custom output
// for Pod type.
tf.OpenAPISchemaFunc = testOpenAPISchemaData
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Resp: &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &pods.Items[0])},
}
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdGet("kubectl", tf, streams)
cmd.SetOut(buf)
cmd.SetErr(buf)
cmd.Flags().Set(useOpenAPIPrintColumnFlagLabel, "true")
cmd.Run(cmd, []string{"pods", "foo"})
expected := `NAME RSRC
foo 10
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
type FakeResources struct {
resources map[schema.GroupVersionKind]proto.Schema
}
func (f FakeResources) LookupResource(s schema.GroupVersionKind) proto.Schema {
return f.resources[s]
}
func (f FakeResources) GetConsumes(gvk schema.GroupVersionKind, operation string) []string {
return nil
}
var _ openapi.Resources = &FakeResources{}
func testOpenAPISchemaData() (openapi.Resources, error) {
return &FakeResources{
resources: map[schema.GroupVersionKind]proto.Schema{
{
Version: "v1",
Kind: "Pod",
}: &proto.Primitive{
BaseSchema: proto.BaseSchema{
Extensions: map[string]interface{}{
"x-kubernetes-print-columns": "custom-columns=NAME:.metadata.name,RSRC:.metadata.resourceVersion",
},
},
},
},
}, nil
}
func TestGetObjects(t *testing.T) { func TestGetObjects(t *testing.T) {
pods, _, _ := cmdtesting.TestData() pods, _, _ := cmdtesting.TestData()

View File

@ -1,27 +0,0 @@
/*
Copyright 2017 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 openapi
import "k8s.io/kube-openapi/pkg/validation/spec"
// PrintColumnsKey is the key that defines which columns should be printed
const PrintColumnsKey = "x-kubernetes-print-columns"
// GetPrintColumns looks for the open API extension for the display columns.
func GetPrintColumns(extensions spec.Extensions) (string, bool) {
return extensions.GetString(PrintColumnsKey)
}