Merge pull request #63599 from deads2k/cli-53-restmapper

Automatic merge from submit-queue (batch tested with PRs 63597, 63599). 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>.

push ToRESTMapper down a layer

The RESTMapper is needed to drive some use-cases for a dynamic client and takes a little bit of wiring (nested restmappers).  This pull pushes that into information derived from the kubeconfig flags to allow easy re-use.

@kubernetes/sig-cli-maintainers 
/assign @juanvallejo 
/assign @soltysh 

assigned to original creators.


```release-note
NONE
```
pull/8/head
Kubernetes Submit Queue 2018-05-09 11:26:12 -07:00 committed by GitHub
commit 23a9136d4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 23 deletions

View File

@ -269,7 +269,8 @@ func NewTestFactory() *TestFactory {
clientConfig := clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, overrides, fallbackReader)
configFlags := cmdutil.NewTestConfigFlags().
WithClientConfig(clientConfig)
WithClientConfig(clientConfig).
WithRESTMapper(testRESTMapper())
return &TestFactory{
Factory: cmdutil.NewFactory(configFlags),
@ -428,7 +429,7 @@ func (f *TestFactory) ClientSetForVersion(requiredVersion *schema.GroupVersion)
return f.ClientSet()
}
func (f *TestFactory) RESTMapper() (meta.RESTMapper, error) {
func testRESTMapper() meta.RESTMapper {
groupResources := testDynamicResources()
mapper := restmapper.NewDiscoveryRESTMapper(groupResources)
// for backwards compatibility with existing tests, allow rest mappings from the scheme to show up
@ -440,10 +441,9 @@ func (f *TestFactory) RESTMapper() (meta.RESTMapper, error) {
},
}
// TODO: should probably be the external scheme
fakeDs := &fakeCachedDiscoveryClient{}
expander := restmapper.NewShortcutExpander(mapper, fakeDs)
return expander, nil
return expander
}
func (f *TestFactory) LogsForObject(object, options runtime.Object, timeout time.Duration) (*restclient.Request, error) {

View File

@ -24,12 +24,16 @@ import (
"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/api/meta"
utilflag "k8s.io/apiserver/pkg/util/flag"
"k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
"k8s.io/client-go/restmapper"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
"fmt"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/transport"
)
@ -198,6 +202,18 @@ func (f *ConfigFlags) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, e
return NewCachedDiscoveryClient(discoveryClient, cacheDir, time.Duration(10*time.Minute)), nil
}
// RESTMapper returns a mapper.
func (f *ConfigFlags) ToRESTMapper() (meta.RESTMapper, error) {
discoveryClient, err := f.ToDiscoveryClient()
if err != nil {
return nil, err
}
mapper := restmapper.NewDeferredDiscoveryRESTMapper(discoveryClient)
expander := restmapper.NewShortcutExpander(mapper, discoveryClient)
return expander, nil
}
func (f *ConfigFlags) AddFlags(flags *pflag.FlagSet) {
flags.SetNormalizeFunc(utilflag.WarnWordSepNormalizeFunc) // Warn for "_" flags
@ -300,6 +316,7 @@ func stringptr(val string) *string {
type TestConfigFlags struct {
clientConfig clientcmd.ClientConfig
discoveryClient discovery.CachedDiscoveryInterface
restMapper meta.RESTMapper
}
func (f *TestConfigFlags) ToRawKubeConfigLoader() clientcmd.ClientConfig {
@ -317,11 +334,28 @@ func (f *TestConfigFlags) ToDiscoveryClient() (discovery.CachedDiscoveryInterfac
return f.discoveryClient, nil
}
func (f *TestConfigFlags) ToRESTMapper() (meta.RESTMapper, error) {
if f.restMapper != nil {
return f.restMapper, nil
}
if f.discoveryClient != nil {
mapper := restmapper.NewDeferredDiscoveryRESTMapper(f.discoveryClient)
expander := restmapper.NewShortcutExpander(mapper, f.discoveryClient)
return expander, nil
}
return nil, fmt.Errorf("no restmapper")
}
func (f *TestConfigFlags) WithClientConfig(clientConfig clientcmd.ClientConfig) *TestConfigFlags {
f.clientConfig = clientConfig
return f
}
func (f *TestConfigFlags) WithRESTMapper(mapper meta.RESTMapper) *TestConfigFlags {
f.restMapper = mapper
return f
}
func (f *TestConfigFlags) WithDiscoveryClient(c discovery.CachedDiscoveryInterface) *TestConfigFlags {
f.discoveryClient = c
return f

View File

@ -98,6 +98,9 @@ type ClientAccessFactory interface {
// KubernetesClientSet gives you back an external clientset
KubernetesClientSet() (*kubernetes.Clientset, error)
// Returns interfaces for dealing with arbitrary runtime.Objects.
RESTMapper() (meta.RESTMapper, error)
// Returns a RESTClient for accessing Kubernetes resources or an error.
RESTClient() (*restclient.RESTClient, error)
// Returns a client.Config for accessing the Kubernetes server.
@ -165,8 +168,6 @@ type ClientAccessFactory interface {
// ObjectMappingFactory holds the second level of factory methods. These functions depend upon ClientAccessFactory methods.
// Generally they provide object typing and functions that build requests based on the negotiated clients.
type ObjectMappingFactory interface {
// Returns interfaces for dealing with arbitrary runtime.Objects.
RESTMapper() (meta.RESTMapper, error)
// Returns interface for expanding categories like `all`.
CategoryExpander() categories.CategoryExpander
// Returns a RESTClient for working with the specified RESTMapping or an error. This is intended

View File

@ -45,7 +45,7 @@ func NewBuilderFactory(clientAccessFactory ClientAccessFactory, objectMappingFac
// NewBuilder returns a new resource builder for structured api objects.
func (f *ring2Factory) NewBuilder() *resource.Builder {
mapper, mapperErr := f.objectMappingFactory.RESTMapper()
mapper, mapperErr := f.clientAccessFactory.RESTMapper()
categoryExpander := f.objectMappingFactory.CategoryExpander()
return resource.NewBuilder(
@ -84,7 +84,7 @@ func (f *ring2Factory) ScaleClient() (scaleclient.ScalesGetter, error) {
return nil, err
}
resolver := scaleclient.NewDiscoveryScaleKindResolver(discoClient)
mapper, err := f.objectMappingFactory.RESTMapper()
mapper, err := f.clientAccessFactory.RESTMapper()
if err != nil {
return nil, err
}

View File

@ -64,6 +64,7 @@ import (
type RESTClientGetter interface {
ToRESTConfig() (*restclient.Config, error)
ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error)
ToRESTMapper() (meta.RESTMapper, error)
ToRawKubeConfigLoader() clientcmd.ClientConfig
}
@ -141,6 +142,11 @@ func (f *ring0Factory) ClientConfig() (*restclient.Config, error) {
setKubernetesDefaults(clientConfig)
return clientConfig, nil
}
func (f *ring0Factory) RESTMapper() (meta.RESTMapper, error) {
return f.clientGetter.ToRESTMapper()
}
func (f *ring0Factory) BareClientConfig() (*restclient.Config, error) {
return f.clientGetter.ToRESTConfig()
}

View File

@ -40,7 +40,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/dynamic"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/restmapper"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/batch"
api "k8s.io/kubernetes/pkg/apis/core"
@ -76,20 +75,6 @@ func NewObjectMappingFactory(clientAccessFactory ClientAccessFactory) ObjectMapp
return f
}
// RESTMapper returns a mapper.
func (f *ring1Factory) RESTMapper() (meta.RESTMapper, error) {
discoveryClient, err := f.clientAccessFactory.DiscoveryClient()
if err != nil {
return nil, err
}
// allow conversion between typed and unstructured objects
mapper := restmapper.NewDeferredDiscoveryRESTMapper(discoveryClient)
// TODO: should this also indicate it recognizes typed objects?
expander := restmapper.NewShortcutExpander(mapper, discoveryClient)
return expander, nil
}
func (f *ring1Factory) CategoryExpander() categories.CategoryExpander {
legacyExpander := categories.LegacyCategoryExpander