1 // Copyright 2019 The Operator-SDK Authors
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
20 "github.com/pkg/errors"
21 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22 "k8s.io/apimachinery/pkg/runtime/schema"
23 "k8s.io/apimachinery/pkg/runtime/serializer"
24 "k8s.io/client-go/dynamic"
25 "k8s.io/client-go/kubernetes"
26 "k8s.io/client-go/kubernetes/scheme"
27 "k8s.io/client-go/rest"
30 func newClientForGVK(cfg *rest.Config, apiVersion, kind string) (dynamic.NamespaceableResourceInterface, error) {
31 apiResourceList, apiResource, err := getAPIResource(cfg, apiVersion, kind)
33 return nil, errors.Wrapf(err, "discovering resource information failed for %s in %s", kind, apiVersion)
36 dc, err := newForConfig(cfg, apiResourceList.GroupVersion)
38 return nil, errors.Wrapf(err, "creating dynamic client failed for %s", apiResourceList.GroupVersion)
41 gv, err := schema.ParseGroupVersion(apiResourceList.GroupVersion)
43 return nil, errors.Wrapf(err, "parsing GroupVersion %s failed", apiResourceList.GroupVersion)
46 gvr := schema.GroupVersionResource{
49 Resource: apiResource.Name,
52 return dc.Resource(gvr), nil
55 func getAPIResource(cfg *rest.Config, apiVersion, kind string) (*metav1.APIResourceList, *metav1.APIResource, error) {
56 kclient, err := kubernetes.NewForConfig(cfg)
61 apiResourceLists, err := kclient.Discovery().ServerResources()
66 for _, apiResourceList := range apiResourceLists {
67 if apiResourceList.GroupVersion == apiVersion {
68 for _, r := range apiResourceList.APIResources {
70 return apiResourceList, &r, nil
76 return nil, nil, fmt.Errorf("apiVersion %s and kind %s not found available in Kubernetes cluster", apiVersion, kind)
79 func newForConfig(c *rest.Config, groupVersion string) (dynamic.Interface, error) {
80 config := rest.CopyConfig(c)
82 err := setConfigDefaults(groupVersion, config)
87 return dynamic.NewForConfig(config)
90 func setConfigDefaults(groupVersion string, config *rest.Config) error {
91 gv, err := schema.ParseGroupVersion(groupVersion)
95 config.GroupVersion = &gv
96 config.APIPath = "/apis"
97 if config.GroupVersion.Group == "" && config.GroupVersion.Version == "v1" {
98 config.APIPath = "/api"
100 config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}