Merge pull request #62877 from deads2k/cli-34-describer

Automatic merge from submit-queue (batch tested with PRs 62982, 63075, 63067, 62877, 63141). 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>.

make describers more generic from the CLI

I've made this change very small so the intent and explanation make sense to people.

Clients are not generic.  Client**Configs** are generic.  We faced this distinction in the apiserver and it took us a little to hurdle it.  When you try to provide a generic example or function, you need to provide Client**Config**, not a kube clientset.  The reason is that the code you're calling may have generated their own clientset, may want to use a dynamic one, or may want to a simple restclient.  As we seek to make `kubectl` primitives more generally applicable, this is an example we'll want to follow.  I suspect we'll be making more changes along these veins as we tease out the generic pieces of `kubectl ` to make a friendly CLI library.


@kubernetes/sig-cli-maintainers 

/hold

Holding for a few days to make sure that people have time to read and digest.

```release-note
NONE
```
This commit is contained in:
Kubernetes Submit Queue 2018-04-25 11:53:21 -07:00 committed by GitHub
commit df489968b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 23 additions and 31 deletions

View File

@ -89,7 +89,6 @@ go_library(
"//pkg/kubectl/util/term:go_default_library",
"//pkg/kubectl/validation:go_default_library",
"//pkg/printers:go_default_library",
"//pkg/printers/internalversion:go_default_library",
"//pkg/util/interrupt:go_default_library",
"//pkg/util/taints:go_default_library",
"//pkg/version:go_default_library",

View File

@ -26,13 +26,11 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
"k8s.io/kubernetes/pkg/printers"
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
)
var (
@ -75,11 +73,6 @@ func NewCmdDescribe(f cmdutil.Factory, out, cmdErr io.Writer) *cobra.Command {
ShowEvents: true,
}
// TODO: this should come from the factory, and may need to be loaded from the server, and so is probably
// going to have to be removed
validArgs := printersinternal.DescribableResources()
argAliases := kubectl.ResourceAliases(validArgs)
cmd := &cobra.Command{
Use: "describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)",
DisableFlagsInUseLine: true,
@ -90,8 +83,6 @@ func NewCmdDescribe(f cmdutil.Factory, out, cmdErr io.Writer) *cobra.Command {
err := RunDescribe(f, out, cmdErr, cmd, args, options, describerSettings)
cmdutil.CheckErr(err)
},
ValidArgs: validArgs,
ArgAliases: argAliases,
}
usage := "containing the resource to describe"
cmdutil.AddFilenameOptionFlags(cmd, options, usage)

View File

@ -164,16 +164,12 @@ func (f *ring1Factory) UnstructuredClientForMapping(mapping *meta.RESTMapping) (
}
func (f *ring1Factory) Describer(mapping *meta.RESTMapping) (printers.Describer, error) {
clientset, err := f.clientAccessFactory.ClientSet()
if err != nil {
return nil, err
}
externalclientset, err := f.clientAccessFactory.KubernetesClientSet()
clientConfig, err := f.clientAccessFactory.ClientConfig()
if err != nil {
return nil, err
}
// try to get a describer
if describer, ok := printersinternal.DescriberFor(mapping.GroupVersionKind.GroupKind(), clientset, externalclientset); ok {
if describer, ok := printersinternal.DescriberFor(mapping.GroupVersionKind.GroupKind(), clientConfig); ok {
return describer, nil
}
// if this is a kind we don't have a describer for yet, go generic if possible

View File

@ -107,6 +107,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/client-go/dynamic:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
],
)

View File

@ -47,6 +47,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/dynamic"
externalclient "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/kubernetes/pkg/api/events"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/api/ref"
@ -123,7 +124,16 @@ func (pw *prefixWriter) Flush() {
}
}
func describerMap(c clientset.Interface, externalclient externalclient.Interface) map[schema.GroupKind]printers.Describer {
func describerMap(clientConfig *rest.Config) (map[schema.GroupKind]printers.Describer, error) {
c, err := clientset.NewForConfig(clientConfig)
if err != nil {
return nil, err
}
externalclient, err := externalclient.NewForConfig(clientConfig)
if err != nil {
return nil, err
}
m := map[schema.GroupKind]printers.Describer{
api.Kind("Pod"): &PodDescriber{c},
api.Kind("ReplicationController"): &ReplicationControllerDescriber{c},
@ -164,24 +174,19 @@ func describerMap(c clientset.Interface, externalclient externalclient.Interface
scheduling.Kind("PriorityClass"): &PriorityClassDescriber{c},
}
return m
}
// DescribableResources lists all resource types we can describe.
func DescribableResources() []string {
keys := make([]string, 0)
for k := range describerMap(nil, nil) {
resource := strings.ToLower(k.Kind)
keys = append(keys, resource)
}
return keys
return m, nil
}
// DescriberFor returns the default describe functions for each of the standard
// Kubernetes types.
func DescriberFor(kind schema.GroupKind, c clientset.Interface, externalclient externalclient.Interface) (printers.Describer, bool) {
f, ok := describerMap(c, externalclient)[kind]
func DescriberFor(kind schema.GroupKind, clientConfig *rest.Config) (printers.Describer, bool) {
describers, err := describerMap(clientConfig)
if err != nil {
glog.V(1).Info(err)
return nil, false
}
f, ok := describers[kind]
return f, ok
}