Unverified Commit 153b5f50 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #53483 from apelisse/openapi-columns

Automatic merge from submit-queue (batch tested with PRs 50457, 55558, 53483, 55731, 52842). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Show openapi custom columns in `kubectl get` Change the name of the flag to something slightly more user-friendly, while making it default true. The flag is kept so that someone can revert it temporarly if things go wrong. **What this PR does / why we need it**: OpenAPI can specify for some columns to be used in `kubectl get`. That's very useful for non-core/hard-coded type in order to print more valuable data in get. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes # **Special notes for your reviewer**: Closes kubernetes/kubectl#143 **Release note**: ```release-note `kubectl get` will now use OpenAPI schema extensions by default to select columns for custom types. ```
parents 1b3d8807 1d99b763
...@@ -197,6 +197,7 @@ go_test( ...@@ -197,6 +197,7 @@ go_test(
], ],
data = [ data = [
"testdata", "testdata",
"//api/openapi-spec:swagger-spec",
"//examples:config", "//examples:config",
"//test/fixtures", "//test/fixtures",
], ],
......
...@@ -32,6 +32,7 @@ go_test( ...@@ -32,6 +32,7 @@ go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["get_test.go"], srcs = ["get_test.go"],
data = [ data = [
"//api/openapi-spec:swagger-spec",
"//examples:config", "//examples:config",
"//test/fixtures", "//test/fixtures",
], ],
...@@ -45,6 +46,7 @@ go_test( ...@@ -45,6 +46,7 @@ go_test(
"//pkg/kubectl/cmd/testing:go_default_library", "//pkg/kubectl/cmd/testing:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library", "//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library", "//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/cmd/util/openapi/testing:go_default_library",
"//pkg/kubectl/scheme:go_default_library", "//pkg/kubectl/scheme:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
......
...@@ -75,7 +75,7 @@ var ( ...@@ -75,7 +75,7 @@ var (
You can filter the list using a label selector and the --selector flag. If the You can filter the list using a label selector and the --selector flag. If the
desired resource type is namespaced you will only see results in your current desired resource type is namespaced you will only see results in your current
namespace unless you pass --all-namespaces. namespace unless you pass --all-namespaces.
This command will hide resources that have completed, such as pods that are This command will hide resources that have completed, such as pods that are
in the Succeeded or Failed phases. You can see the full results for any in the Succeeded or Failed phases. You can see the full results for any
resource by providing the --show-all flag. Uninitialized objects are not resource by providing the --show-all flag. Uninitialized objects are not
...@@ -114,7 +114,7 @@ var ( ...@@ -114,7 +114,7 @@ var (
) )
const ( const (
useOpenAPIPrintColumnFlagLabel = "experimental-use-openapi-print-columns" useOpenAPIPrintColumnFlagLabel = "use-openapi-print-columns"
) )
// NewCmdGet creates a command object for the generic "get" action, which // NewCmdGet creates a command object for the generic "get" action, which
...@@ -647,9 +647,7 @@ func (options *GetOptions) printGeneric(printer printers.ResourcePrinter, r *res ...@@ -647,9 +647,7 @@ func (options *GetOptions) printGeneric(printer printers.ResourcePrinter, r *res
} }
func addOpenAPIPrintColumnFlags(cmd *cobra.Command) { func addOpenAPIPrintColumnFlags(cmd *cobra.Command) {
cmd.Flags().Bool(useOpenAPIPrintColumnFlagLabel, false, "If true, use x-kubernetes-print-column metadata (if present) from the OpenAPI schema for displaying a resource.") cmd.Flags().Bool(useOpenAPIPrintColumnFlagLabel, true, "If true, use x-kubernetes-print-column metadata (if present) from the OpenAPI schema for displaying a resource.")
// marking it deprecated so that it is hidden from usage/help text.
cmd.Flags().MarkDeprecated(useOpenAPIPrintColumnFlagLabel, "This flag is experimental and may be removed in the future.")
} }
func shouldGetNewPrinterForMapping(printer printers.ResourcePrinter, lastMapping, mapping *meta.RESTMapping) bool { func shouldGetNewPrinterForMapping(printer printers.ResourcePrinter, lastMapping, mapping *meta.RESTMapping) bool {
......
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"path/filepath"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
...@@ -49,9 +50,12 @@ import ( ...@@ -49,9 +50,12 @@ import (
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi" "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
openapitesting "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
) )
var openapiSchemaPath = filepath.Join("..", "..", "..", "..", "api", "openapi-spec", "swagger.json")
// This init should be removed after switching this command and its tests to user external types. // This init should be removed after switching this command and its tests to user external types.
func init() { func init() {
api.AddToScheme(scheme.Scheme) api.AddToScheme(scheme.Scheme)
...@@ -206,6 +210,7 @@ func TestGetUnknownSchemaObject(t *testing.T) { ...@@ -206,6 +210,7 @@ func TestGetUnknownSchemaObject(t *testing.T) {
f, tf, _, _ := cmdtesting.NewAPIFactory() f, tf, _, _ := cmdtesting.NewAPIFactory()
_, _, codec, _ := cmdtesting.NewTestFactory() _, _, codec, _ := cmdtesting.NewTestFactory()
tf.Printer = &testPrinter{} tf.Printer = &testPrinter{}
tf.OpenAPISchemaFunc = openapitesting.CreateOpenAPISchemaFunc(openapiSchemaPath)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: unstructuredSerializer,
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, cmdtesting.NewInternalType("", "", "foo"))}, Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, cmdtesting.NewInternalType("", "", "foo"))},
......
...@@ -22,6 +22,7 @@ go_library( ...@@ -22,6 +22,7 @@ go_library(
"//pkg/kubectl/categories:go_default_library", "//pkg/kubectl/categories:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library", "//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library", "//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/cmd/util/openapi/testing:go_default_library",
"//pkg/kubectl/plugins:go_default_library", "//pkg/kubectl/plugins:go_default_library",
"//pkg/kubectl/resource:go_default_library", "//pkg/kubectl/resource:go_default_library",
"//pkg/kubectl/validation:go_default_library", "//pkg/kubectl/validation:go_default_library",
......
...@@ -45,6 +45,7 @@ import ( ...@@ -45,6 +45,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/categories" "k8s.io/kubernetes/pkg/kubectl/categories"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi" "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
openapitesting "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
"k8s.io/kubernetes/pkg/kubectl/plugins" "k8s.io/kubernetes/pkg/kubectl/plugins"
"k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/validation" "k8s.io/kubernetes/pkg/kubectl/validation"
...@@ -823,7 +824,7 @@ func (f *fakeAPIFactory) OpenAPISchema() (openapi.Resources, error) { ...@@ -823,7 +824,7 @@ func (f *fakeAPIFactory) OpenAPISchema() (openapi.Resources, error) {
if f.tf.OpenAPISchemaFunc != nil { if f.tf.OpenAPISchemaFunc != nil {
return f.tf.OpenAPISchemaFunc() return f.tf.OpenAPISchemaFunc()
} }
return nil, nil return openapitesting.EmptyResources{}, nil
} }
func NewAPIFactory() (cmdutil.Factory, *TestFactory, runtime.Codec, runtime.NegotiatedSerializer) { func NewAPIFactory() (cmdutil.Factory, *TestFactory, runtime.Codec, runtime.NegotiatedSerializer) {
......
...@@ -121,3 +121,20 @@ func (f *FakeResources) LookupResource(gvk schema.GroupVersionKind) proto.Schema ...@@ -121,3 +121,20 @@ func (f *FakeResources) LookupResource(gvk schema.GroupVersionKind) proto.Schema
} }
return resources.LookupResource(gvk) return resources.LookupResource(gvk)
} }
// EmptyResources implement a Resources that just doesn't have any resources.
type EmptyResources struct{}
var _ openapi.Resources = EmptyResources{}
// LookupResource will always return nil. It doesn't have any resources.
func (f EmptyResources) LookupResource(gvk schema.GroupVersionKind) proto.Schema {
return nil
}
// CreateOpenAPISchemaFunc returns a function useful for the TestFactory.
func CreateOpenAPISchemaFunc(path string) func() (openapi.Resources, error) {
return func() (openapi.Resources, error) {
return NewFakeResources(path), nil
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment