github.com/oam-dev/kubevela@v1.9.11/pkg/utils/common/args.go (about)

     1  /*
     2  Copyright 2021 The KubeVela 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 common
    18  
    19  import (
    20  	"fmt"
    21  
    22  	pkgmulticluster "github.com/kubevela/pkg/multicluster"
    23  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    24  	"k8s.io/apimachinery/pkg/runtime"
    25  	"k8s.io/client-go/discovery"
    26  	"k8s.io/client-go/rest"
    27  	"k8s.io/client-go/tools/clientcmd"
    28  	"k8s.io/client-go/tools/clientcmd/api"
    29  	"k8s.io/client-go/util/flowcontrol"
    30  	"sigs.k8s.io/controller-runtime/pkg/client"
    31  	"sigs.k8s.io/controller-runtime/pkg/client/config"
    32  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    33  
    34  	"github.com/kubevela/workflow/pkg/cue/packages"
    35  )
    36  
    37  // Args is args for controller-runtime client
    38  type Args struct {
    39  	config    *rest.Config
    40  	rawConfig *api.Config
    41  	Schema    *runtime.Scheme
    42  	client    client.Client
    43  	pd        *packages.PackageDiscover
    44  	dc        *discovery.DiscoveryClient
    45  }
    46  
    47  // SetConfig insert kubeconfig into Args
    48  func (a *Args) SetConfig(c *rest.Config) error {
    49  	if c != nil {
    50  		a.config = c
    51  		return nil
    52  	}
    53  	restConf, err := config.GetConfig()
    54  	if err != nil {
    55  		return err
    56  	}
    57  	restConf.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(100, 200)
    58  	a.config = restConf
    59  	return nil
    60  }
    61  
    62  // GetConfig get config, if not exist, will create
    63  func (a *Args) GetConfig() (*rest.Config, error) {
    64  	if a.config != nil {
    65  		return a.config, nil
    66  	}
    67  	if err := a.SetConfig(nil); err != nil {
    68  		return nil, err
    69  	}
    70  	return a.config, nil
    71  }
    72  
    73  // GetRawConfig get raw kubeconfig, if not exist, will create
    74  func (a *Args) GetRawConfig() (*api.Config, error) {
    75  	if a.rawConfig != nil {
    76  		return a.rawConfig, nil
    77  	}
    78  	loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
    79  	raw, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
    80  		loadingRules, nil).RawConfig()
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  	return &raw, nil
    85  }
    86  
    87  // GetNamespaceFromConfig will get namespace from kube config
    88  func (a *Args) GetNamespaceFromConfig() string {
    89  	conf, err := a.GetRawConfig()
    90  	if err != nil || conf == nil || conf.Contexts == nil {
    91  		return ""
    92  	}
    93  	ctx, ok := conf.Contexts[conf.CurrentContext]
    94  	if !ok {
    95  		return ""
    96  	}
    97  	return ctx.Namespace
    98  }
    99  
   100  // SetClient set custom client
   101  func (a *Args) SetClient(c client.Client) {
   102  	a.client = c
   103  }
   104  
   105  // GetClient get client if exist
   106  func (a *Args) GetClient() (client.Client, error) {
   107  	if a.client != nil {
   108  		return a.client, nil
   109  	}
   110  	if a.config == nil {
   111  		if err := a.SetConfig(nil); err != nil {
   112  			return nil, err
   113  		}
   114  	}
   115  	newClient, err := pkgmulticluster.NewClient(a.config,
   116  		pkgmulticluster.ClientOptions{
   117  			Options: client.Options{Scheme: a.Schema}})
   118  	if err != nil {
   119  		return nil, err
   120  	}
   121  	a.client = newClient
   122  	return a.client, nil
   123  }
   124  
   125  // GetFakeClient returns a fake client with the definition objects preloaded
   126  func (a *Args) GetFakeClient(defs []*unstructured.Unstructured) (client.Client, error) {
   127  	if a.client != nil {
   128  		return a.client, nil
   129  	}
   130  	if a.config == nil {
   131  		if err := a.SetConfig(&rest.Config{}); err != nil {
   132  			return nil, err
   133  		}
   134  	}
   135  	objs := make([]client.Object, 0, len(defs))
   136  	for _, def := range defs {
   137  		objs = append(objs, def)
   138  	}
   139  	return fake.NewClientBuilder().WithObjects(objs...).WithScheme(a.Schema).Build(), nil
   140  }
   141  
   142  // GetPackageDiscover get PackageDiscover client if exist, create if not exist.
   143  func (a *Args) GetPackageDiscover() (*packages.PackageDiscover, error) {
   144  	if a.config == nil {
   145  		if err := a.SetConfig(nil); err != nil {
   146  			return nil, err
   147  		}
   148  	}
   149  	if a.pd != nil {
   150  		return a.pd, nil
   151  	}
   152  	pd, err := packages.NewPackageDiscover(a.config)
   153  	if err != nil {
   154  		return nil, fmt.Errorf("failed to create CRD discovery for CUE package client %w", err)
   155  	}
   156  	a.pd = pd
   157  	return pd, nil
   158  }
   159  
   160  // GetDiscoveryClient return a discovery client from cli args
   161  func (a *Args) GetDiscoveryClient() (*discovery.DiscoveryClient, error) {
   162  	if a.dc != nil {
   163  		return a.dc, nil
   164  	}
   165  	cfg, err := a.GetConfig()
   166  	if err != nil {
   167  		return nil, err
   168  	}
   169  
   170  	dc, err := discovery.NewDiscoveryClientForConfig(cfg)
   171  	if err != nil {
   172  		return nil, err
   173  	}
   174  	a.dc = dc
   175  	return dc, nil
   176  }