construct resource.Builder from kubeconfig flags

pull/8/head
David Eads 2018-05-09 13:53:07 -04:00
parent 0ba80021c5
commit 1f5357034b
9 changed files with 39 additions and 27 deletions

View File

@ -109,6 +109,10 @@ type ClientAccessFactory interface {
// just directions to the server. People use this to build RESTMappers on top of
BareClientConfig() (*restclient.Config, error)
// NewBuilder returns an object that assists in loading objects from both disk and the server
// and which implements the common patterns for CLI interactions with generic resources.
NewBuilder() *resource.Builder
// UpdatePodSpecForObject will call the provided function on the pod spec this object supports,
// return false if no pod spec is supported, or return an error.
UpdatePodSpecForObject(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error)
@ -204,9 +208,6 @@ type ObjectMappingFactory interface {
// BuilderFactory holds the third level of factory methods. These functions depend upon ObjectMappingFactory and ClientAccessFactory methods.
// Generally they depend upon client mapper functions
type BuilderFactory interface {
// NewBuilder returns an object that assists in loading objects from both disk and the server
// and which implements the common patterns for CLI interactions with generic resources.
NewBuilder() *resource.Builder
// PluginLoader provides the implementation to be used to load cli plugins.
PluginLoader() plugins.PluginLoader
// PluginRunner provides the implementation to be used to run cli plugins.

View File

@ -26,7 +26,6 @@ import (
scaleclient "k8s.io/client-go/scale"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/plugins"
"k8s.io/kubernetes/pkg/kubectl/resource"
)
type ring2Factory struct {
@ -43,20 +42,6 @@ func NewBuilderFactory(clientAccessFactory ClientAccessFactory, objectMappingFac
return f
}
// NewBuilder returns a new resource builder for structured api objects.
func (f *ring2Factory) NewBuilder() *resource.Builder {
mapper, mapperErr := f.clientAccessFactory.RESTMapper()
categoryExpander, categoryExpanderError := f.objectMappingFactory.CategoryExpander()
return resource.NewBuilder(
f.clientAccessFactory.ClientConfig,
mapper,
categoryExpander,
).
AddError(mapperErr).
AddError(categoryExpanderError)
}
// PluginLoader loads plugins from a path set by the KUBECTL_PLUGINS_PATH env var.
// If this env var is not set, it defaults to
// "~/.kube/plugins", plus

View File

@ -151,6 +151,11 @@ func (f *ring0Factory) BareClientConfig() (*restclient.Config, error) {
return f.clientGetter.ToRESTConfig()
}
// NewBuilder returns a new resource builder for structured api objects.
func (f *ring0Factory) NewBuilder() *resource.Builder {
return resource.NewBuilder(f.clientGetter)
}
func (f *ring0Factory) RESTClient() (*restclient.RESTClient, error) {
clientConfig, err := f.ClientConfig()
if err != nil {

View File

@ -81,7 +81,7 @@ func (f *ring1Factory) CategoryExpander() (restmapper.CategoryExpander, error) {
return nil, err
}
return restmapper.NewDiscoveryCategoryExpander(discoveryClient)
return restmapper.NewDiscoveryCategoryExpander(discoveryClient), nil
}
func (f *ring1Factory) ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) {

View File

@ -42,6 +42,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/discovery:go_default_library",
"//vendor/k8s.io/client-go/dynamic:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/restmapper:go_default_library",

View File

@ -144,7 +144,7 @@ type resourceTuple struct {
type FakeClientFunc func(version schema.GroupVersion) (RESTClient, error)
func NewFakeBuilder(fakeClientFn FakeClientFunc, restMapper meta.RESTMapper, categoryExpander restmapper.CategoryExpander) *Builder {
ret := NewBuilder(nil, restMapper, categoryExpander)
ret := newBuilder(nil, restMapper, categoryExpander)
ret.fakeClientFn = fakeClientFn
return ret
}
@ -153,7 +153,7 @@ func NewFakeBuilder(fakeClientFn FakeClientFunc, restMapper meta.RESTMapper, cat
// internal or unstructured must be specified.
// TODO: Add versioned client (although versioned is still lossy)
// TODO remove internal and unstructured mapper and instead have them set the negotiated serializer for use in the client
func NewBuilder(clientConfigFn ClientConfigFunc, restMapper meta.RESTMapper, categoryExpander restmapper.CategoryExpander) *Builder {
func newBuilder(clientConfigFn ClientConfigFunc, restMapper meta.RESTMapper, categoryExpander restmapper.CategoryExpander) *Builder {
return &Builder{
clientConfigFn: clientConfigFn,
restMapper: restMapper,
@ -162,6 +162,21 @@ func NewBuilder(clientConfigFn ClientConfigFunc, restMapper meta.RESTMapper, cat
}
}
func NewBuilder(restClientGetter RESTClientGetter) *Builder {
restMapper, mapperErr := restClientGetter.ToRESTMapper()
discoveryClient, discoveryErr := restClientGetter.ToDiscoveryClient()
var categoryExpander restmapper.CategoryExpander
if discoveryErr == nil {
categoryExpander = restmapper.NewDiscoveryCategoryExpander(discoveryClient)
}
return newBuilder(
restClientGetter.ToRESTConfig,
restMapper,
categoryExpander,
).AddError(mapperErr).AddError(discoveryErr)
}
func (b *Builder) Schema(schema validation.Schema) *Builder {
b.schema = schema
return b

View File

@ -17,10 +17,18 @@ limitations under the License.
package resource
import (
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
)
type RESTClientGetter interface {
ToRESTConfig() (*rest.Config, error)
ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error)
ToRESTMapper() (meta.RESTMapper, error)
}
type ClientConfigFunc func() (*rest.Config, error)
// RESTClient is a client helper for dealing with RESTful resources

View File

@ -48,11 +48,11 @@ type discoveryCategoryExpander struct {
// NewDiscoveryCategoryExpander returns a category expander that makes use of the "categories" fields from
// the API, found through the discovery client. In case of any error or no category found (which likely
// means we're at a cluster prior to categories support, fallback to the expander provided.
func NewDiscoveryCategoryExpander(client discovery.DiscoveryInterface) (CategoryExpander, error) {
func NewDiscoveryCategoryExpander(client discovery.DiscoveryInterface) CategoryExpander {
if client == nil {
panic("Please provide discovery client to shortcut expander")
}
return discoveryCategoryExpander{discoveryClient: client}, nil
return discoveryCategoryExpander{discoveryClient: client}
}
// Expand fulfills CategoryExpander

View File

@ -135,10 +135,7 @@ func TestDiscoveryCategoryExpander(t *testing.T) {
dc.serverResourcesHandler = func() ([]*metav1.APIResourceList, error) {
return test.serverResponse, nil
}
expander, err := NewDiscoveryCategoryExpander(dc)
if err != nil {
t.Fatalf("unexpected error %v", err)
}
expander := NewDiscoveryCategoryExpander(dc)
expanded, _ := expander.Expand(test.category)
if !reflect.DeepEqual(expanded, test.expected) {
t.Errorf("expected %v, got %v", test.expected, expanded)