From c838f695a4eac096e53883be383d802d199ed3b8 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Wed, 28 Oct 2020 00:44:25 +0000 Subject: [PATCH] chore: remove custom factory Signed-off-by: Leonardo Di Donato --- pkg/factory/factory.go | 197 ---------------------------------- pkg/factory/matchversion.go | 92 ---------------- pkg/factory/setk8sdefaults.go | 27 ----- 3 files changed, 316 deletions(-) delete mode 100644 pkg/factory/factory.go delete mode 100644 pkg/factory/matchversion.go delete mode 100644 pkg/factory/setk8sdefaults.go diff --git a/pkg/factory/factory.go b/pkg/factory/factory.go deleted file mode 100644 index a4e7c259..00000000 --- a/pkg/factory/factory.go +++ /dev/null @@ -1,197 +0,0 @@ -package factory - -import ( - "sync" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/cli-runtime/pkg/genericclioptions" - "k8s.io/cli-runtime/pkg/resource" - "k8s.io/client-go/discovery" - "k8s.io/client-go/dynamic" - "k8s.io/client-go/kubernetes" - restclient "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi" - openapivalidation "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation" - "k8s.io/kubernetes/pkg/kubectl/validation" -) - -// Factory provides abstractions that allow the kubectl command to be extended across multiple types of resources and different API sets. -// The rings are here for a reason. -// In order for composers to be able to provide alternative factory implementations -// they need to provide low level pieces of *certain* functions so that when the factory calls back into itself -// it uses the custom version of the function. Rather than try to enumerate everything that someone would want to override -// we split the factory into rings, where each ring can depend on methods in an earlier ring, but cannot depend -// upon peer methods in its own ring. -// TODO: make the functions interfaces -type Factory interface { - genericclioptions.RESTClientGetter - - // DynamicClient returns a dynamic client ready for use - DynamicClient() (dynamic.Interface, error) - - // KubernetesClientSet gives you back an external clientset - KubernetesClientSet() (*kubernetes.Clientset, error) - - // Returns a RESTClient for accessing Kubernetes resources or an error. - RESTClient() (*restclient.RESTClient, 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 - - // Returns a RESTClient for working with the specified RESTMapping or an error. This is intended - // for working with arbitrary resources and is not guaranteed to point to a Kubernetes APIServer. - ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) - - // Returns a RESTClient for working with Unstructured objects. - UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) - - // Returns a schema that can validate objects stored on disk. - Validator(validate bool) (validation.Schema, error) - - // OpenAPISchema returns the schema openapi schema definition - OpenAPISchema() (openapi.Resources, error) -} - -type factoryImpl struct { - clientGetter genericclioptions.RESTClientGetter - - // openAPIGetter loads and caches openapi specs - openAPIGetter openAPIGetter -} - -type openAPIGetter struct { - once sync.Once - getter openapi.Getter -} - -func NewFactory(clientGetter genericclioptions.RESTClientGetter) Factory { - if clientGetter == nil { - panic("attempt to instantiate client_access_factory with nil clientGetter") - } - - f := &factoryImpl{ - clientGetter: clientGetter, - } - - return f -} - -func (f *factoryImpl) ToRESTConfig() (*restclient.Config, error) { - return f.clientGetter.ToRESTConfig() -} - -func (f *factoryImpl) ToRESTMapper() (meta.RESTMapper, error) { - return f.clientGetter.ToRESTMapper() -} - -func (f *factoryImpl) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) { - return f.clientGetter.ToDiscoveryClient() -} - -func (f *factoryImpl) ToRawKubeConfigLoader() clientcmd.ClientConfig { - return f.clientGetter.ToRawKubeConfigLoader() -} - -func (f *factoryImpl) KubernetesClientSet() (*kubernetes.Clientset, error) { - clientConfig, err := f.ToRESTConfig() - if err != nil { - return nil, err - } - return kubernetes.NewForConfig(clientConfig) -} - -func (f *factoryImpl) DynamicClient() (dynamic.Interface, error) { - clientConfig, err := f.ToRESTConfig() - if err != nil { - return nil, err - } - return dynamic.NewForConfig(clientConfig) -} - -// NewBuilder returns a new resource builder for structured api objects. -func (f *factoryImpl) NewBuilder() *resource.Builder { - return resource.NewBuilder(f.clientGetter) -} - -func (f *factoryImpl) RESTClient() (*restclient.RESTClient, error) { - clientConfig, err := f.ToRESTConfig() - if err != nil { - return nil, err - } - setKubernetesDefaults(clientConfig) - return restclient.RESTClientFor(clientConfig) -} - -func (f *factoryImpl) ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) { - cfg, err := f.clientGetter.ToRESTConfig() - if err != nil { - return nil, err - } - if err := setKubernetesDefaults(cfg); err != nil { - return nil, err - } - gvk := mapping.GroupVersionKind - switch gvk.Group { - case corev1.GroupName: - cfg.APIPath = "/api" - default: - cfg.APIPath = "/apis" - } - gv := gvk.GroupVersion() - cfg.GroupVersion = &gv - return restclient.RESTClientFor(cfg) -} - -func (f *factoryImpl) UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) { - cfg, err := f.clientGetter.ToRESTConfig() - if err != nil { - return nil, err - } - if err := restclient.SetKubernetesDefaults(cfg); err != nil { - return nil, err - } - cfg.APIPath = "/apis" - if mapping.GroupVersionKind.Group == corev1.GroupName { - cfg.APIPath = "/api" - } - gv := mapping.GroupVersionKind.GroupVersion() - cfg.ContentConfig = resource.UnstructuredPlusDefaultContentConfig() - cfg.GroupVersion = &gv - return restclient.RESTClientFor(cfg) -} - -func (f *factoryImpl) Validator(validate bool) (validation.Schema, error) { - if !validate { - return validation.NullSchema{}, nil - } - - resources, err := f.OpenAPISchema() - if err != nil { - return nil, err - } - - return validation.ConjunctiveSchema{ - openapivalidation.NewSchemaValidation(resources), - validation.NoDoubleKeySchema{}, - }, nil -} - -// OpenAPISchema returns metadata and structural information about Kubernetes object definitions. -func (f *factoryImpl) OpenAPISchema() (openapi.Resources, error) { - discovery, err := f.clientGetter.ToDiscoveryClient() - if err != nil { - return nil, err - } - - // Lazily initialize the OpenAPIGetter once - f.openAPIGetter.once.Do(func() { - // Create the caching OpenAPIGetter - f.openAPIGetter.getter = openapi.NewOpenAPIGetter(discovery) - }) - - // Delegate to the OpenAPIGetter - return f.openAPIGetter.getter.Get() -} diff --git a/pkg/factory/matchversion.go b/pkg/factory/matchversion.go deleted file mode 100644 index 66d48782..00000000 --- a/pkg/factory/matchversion.go +++ /dev/null @@ -1,92 +0,0 @@ -package factory - -import ( - "sync" - - "github.com/spf13/pflag" - - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/client-go/discovery" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - - "k8s.io/cli-runtime/pkg/genericclioptions" - "k8s.io/kubernetes/pkg/version" -) - -const ( - flagMatchBinaryVersion = "match-server-version" -) - -// MatchVersionFlags is for setting the "match server version" function. -type MatchVersionFlags struct { - Delegate genericclioptions.RESTClientGetter - - RequireMatchedServerVersion bool - checkServerVersion sync.Once - matchesServerVersionErr error -} - -var _ genericclioptions.RESTClientGetter = &MatchVersionFlags{} - -func (f *MatchVersionFlags) checkMatchingServerVersion() error { - f.checkServerVersion.Do(func() { - if !f.RequireMatchedServerVersion { - return - } - discoveryClient, err := f.Delegate.ToDiscoveryClient() - if err != nil { - f.matchesServerVersionErr = err - return - } - f.matchesServerVersionErr = discovery.MatchesServerVersion(version.Get(), discoveryClient) - }) - - return f.matchesServerVersionErr -} - -// ToRESTConfig implements RESTClientGetter. -// Returns a REST client configuration based on a provided path -// to a .kubeconfig file, loading rules, and config flag overrides. -// Expects the AddFlags method to have been called. -func (f *MatchVersionFlags) ToRESTConfig() (*rest.Config, error) { - if err := f.checkMatchingServerVersion(); err != nil { - return nil, err - } - clientConfig, err := f.Delegate.ToRESTConfig() - if err != nil { - return nil, err - } - // TODO we should not have to do this. It smacks of something going wrong. - setKubernetesDefaults(clientConfig) - return clientConfig, nil -} - -func (f *MatchVersionFlags) ToRawKubeConfigLoader() clientcmd.ClientConfig { - return f.Delegate.ToRawKubeConfigLoader() -} - -func (f *MatchVersionFlags) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) { - if err := f.checkMatchingServerVersion(); err != nil { - return nil, err - } - return f.Delegate.ToDiscoveryClient() -} - -// RESTMapper returns a mapper. -func (f *MatchVersionFlags) ToRESTMapper() (meta.RESTMapper, error) { - if err := f.checkMatchingServerVersion(); err != nil { - return nil, err - } - return f.Delegate.ToRESTMapper() -} - -func (f *MatchVersionFlags) AddFlags(flags *pflag.FlagSet) { - flags.BoolVar(&f.RequireMatchedServerVersion, flagMatchBinaryVersion, f.RequireMatchedServerVersion, "Require server version to match client version") -} - -func NewMatchVersionFlags(delegate genericclioptions.RESTClientGetter) *MatchVersionFlags { - return &MatchVersionFlags{ - Delegate: delegate, - } -} diff --git a/pkg/factory/setk8sdefaults.go b/pkg/factory/setk8sdefaults.go deleted file mode 100644 index 3dcc6ee4..00000000 --- a/pkg/factory/setk8sdefaults.go +++ /dev/null @@ -1,27 +0,0 @@ -package factory - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/runtime/serializer" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" -) - -// setKubernetesDefaults sets default values on the provided client config for accessing the -// Kubernetes API or returns an error if any of the defaults are impossible or invalid. -// TODO this isn't what we want. Each clientset should be setting defaults as it sees fit. -func setKubernetesDefaults(config *rest.Config) error { - // TODO remove this hack. This is allowing the GetOptions to be serialized. - config.GroupVersion = &schema.GroupVersion{Group: "", Version: "v1"} - - if config.APIPath == "" { - config.APIPath = "/api" - } - if config.NegotiatedSerializer == nil { - // This codec factory ensures the resources are not converted. Therefore, resources - // will not be round-tripped through internal versions. Defaulting does not happen - // on the client. - config.NegotiatedSerializer = &serializer.DirectCodecFactory{CodecFactory: scheme.Codecs} - } - return rest.SetKubernetesDefaults(config) -}