github.com/kubewharf/katalyst-core@v0.5.3/pkg/client/genericclient.go (about)

     1  /*
     2  Copyright 2022 The Katalyst Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  // Package client is the package that generate K8S kubeConfig and clientSet; and
    18  // any new CRD and its corresponding clientSet should be added here.
    19  // besides, this package is the only package that update/patch actions should happen.
    20  package client // import "github.com/kubewharf/katalyst-core/pkg/client"
    21  
    22  import (
    23  	"fmt"
    24  
    25  	"k8s.io/apimachinery/pkg/runtime"
    26  	"k8s.io/client-go/discovery"
    27  	"k8s.io/client-go/dynamic"
    28  	"k8s.io/client-go/kubernetes"
    29  	"k8s.io/client-go/metadata"
    30  	"k8s.io/client-go/rest"
    31  	"k8s.io/client-go/tools/clientcmd"
    32  	componentbaseconfig "k8s.io/component-base/config"
    33  	aggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
    34  	"k8s.io/metrics/pkg/client/custom_metrics"
    35  	customclient "k8s.io/metrics/pkg/client/custom_metrics"
    36  	cmfake "k8s.io/metrics/pkg/client/custom_metrics/fake"
    37  	"k8s.io/metrics/pkg/client/external_metrics"
    38  	externalclient "k8s.io/metrics/pkg/client/external_metrics"
    39  	emfake "k8s.io/metrics/pkg/client/external_metrics/fake"
    40  	"sigs.k8s.io/custom-metrics-apiserver/pkg/dynamicmapper"
    41  
    42  	clientset "github.com/kubewharf/katalyst-api/pkg/client/clientset/versioned"
    43  )
    44  
    45  // GenericClientSet defines a generic client contains clients that are needed
    46  type GenericClientSet struct {
    47  	cfg *rest.Config
    48  
    49  	MetaClient       metadata.Interface
    50  	KubeClient       kubernetes.Interface
    51  	InternalClient   clientset.Interface
    52  	DynamicClient    dynamic.Interface
    53  	DiscoveryClient  discovery.DiscoveryInterface
    54  	AggregatorClient aggregator.Interface
    55  
    56  	CustomClient   customclient.CustomMetricsClient
    57  	ExternalClient externalclient.ExternalMetricsClient
    58  }
    59  
    60  // BuildMetricClient builds kubernetes native metrics-clients; and metrics-clients
    61  // can't be build in init process, since discovery mapper will be initialized at the
    62  // same time, which is usually not needed for agents (to avoid too many connections).
    63  func (g *GenericClientSet) BuildMetricClient(mapper *dynamicmapper.RegeneratingDiscoveryRESTMapper) {
    64  	apiVersionsGetter := custom_metrics.NewAvailableAPIsGetter(g.KubeClient.Discovery())
    65  	g.CustomClient = custom_metrics.NewForConfig(g.cfg, mapper, apiVersionsGetter)
    66  	g.ExternalClient = external_metrics.NewForConfigOrDie(g.cfg)
    67  	g.AggregatorClient = aggregator.NewForConfigOrDie(g.cfg)
    68  }
    69  
    70  // newForConfig creates a new clientSet for the given config.
    71  func newForConfig(cfg *rest.Config) (*GenericClientSet, error) {
    72  	cWithProtobuf := rest.CopyConfig(cfg)
    73  	cWithProtobuf.ContentType = runtime.ContentTypeProtobuf
    74  
    75  	metaClient, err := metadata.NewForConfig(cWithProtobuf)
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	kubeClient, err := kubernetes.NewForConfig(cWithProtobuf)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  
    85  	internalClient, err := clientset.NewForConfig(cfg)
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  
    90  	dynamicClient, err := dynamic.NewForConfig(cfg)
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  
    95  	discoveryClient, err := discovery.NewDiscoveryClientForConfig(cfg)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  
   100  	return &GenericClientSet{
   101  		cfg:             cfg,
   102  		MetaClient:      metaClient,
   103  		KubeClient:      kubeClient,
   104  		InternalClient:  internalClient,
   105  		DynamicClient:   dynamicClient,
   106  		DiscoveryClient: discoveryClient,
   107  
   108  		CustomClient:   &cmfake.FakeCustomMetricsClient{},
   109  		ExternalClient: &emfake.FakeExternalMetricsClient{},
   110  	}, nil
   111  }
   112  
   113  // newForConfigOrDie creates a new clientSet for the given config.
   114  func newForConfigOrDie(cfg *rest.Config) *GenericClientSet {
   115  	gc, err := newForConfig(cfg)
   116  	if err != nil {
   117  		panic(err)
   118  	}
   119  	return gc
   120  }
   121  
   122  // BuildGenericClient returns KubeConfig for given master and KubeConfig raw string
   123  func BuildGenericClient(config componentbaseconfig.ClientConnectionConfiguration, masterURL, kubeConfig, name string) (*GenericClientSet, error) {
   124  	inputMasterURL := masterURL
   125  
   126  	// if kube-config is empty, use in cluster configuration
   127  	if kubeConfig == "" {
   128  		masterURL = ""
   129  	}
   130  
   131  	cfg, err := clientcmd.BuildConfigFromFlags(masterURL, kubeConfig)
   132  	if err != nil {
   133  		return nil, fmt.Errorf("BuildConfigFromFlags err:%v", err)
   134  	}
   135  
   136  	if inputMasterURL != "" {
   137  		cfg.Host = inputMasterURL
   138  	}
   139  
   140  	// reset configurations according to client-connection configs
   141  	cfg.DisableCompression = true
   142  	cfg.AcceptContentTypes = config.AcceptContentTypes
   143  	cfg.ContentType = config.ContentType
   144  	cfg.QPS = config.QPS
   145  	cfg.Burst = int(config.Burst)
   146  	cfg.UserAgent = fmt.Sprintf("%s/%s", cfg.UserAgent, name)
   147  
   148  	return newForConfigOrDie(cfg), nil
   149  }