From 44e3c5e351058c6adf4b335037fa6c1a756bfba0 Mon Sep 17 00:00:00 2001 From: carlory Date: Sat, 16 Jul 2022 15:12:34 +0800 Subject: [PATCH] introduce factoryexpansion interface for karmadactl Signed-off-by: carlory --- pkg/karmadactl/util/factory.go | 104 +++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 pkg/karmadactl/util/factory.go diff --git a/pkg/karmadactl/util/factory.go b/pkg/karmadactl/util/factory.go new file mode 100644 index 000000000..a02a75972 --- /dev/null +++ b/pkg/karmadactl/util/factory.go @@ -0,0 +1,104 @@ +package util + +import ( + "context" + "fmt" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/cli-runtime/pkg/genericclioptions" + cmdutil "k8s.io/kubectl/pkg/cmd/util" + + karmadaclientset "github.com/karmada-io/karmada/pkg/generated/clientset/versioned" +) + +const proxyURL = "/apis/cluster.karmada.io/v1alpha1/clusters/%s/proxy/" + +// The Factory interface provides 2 major features compared to the cmdutil.Factory: +// 1. provides a method to get a karmada clientset +// 2. provides a method to get a cmdutil.Factory for the member cluster +type Factory interface { + cmdutil.Factory + + // KarmadaClientSet returns a karmada clientset + KarmadaClientSet() (karmadaclientset.Interface, error) + + // FacotryForMemberCluster returns a cmdutil.Factory for the member cluster + FactoryForMemberCluster(clusterName string) (cmdutil.Factory, error) +} + +var _ Factory = &factoryImpl{} + +// factoryImpl is the implementation of Factory +type factoryImpl struct { + cmdutil.Factory + + // kubeConfigFlags holds all the flags specificed by user. + // These flags will be inherited by the member cluster's client. + kubeConfigFlags *genericclioptions.ConfigFlags +} + +// NewFactory returns a new factory +func NewFactory(kubeConfigFlags *genericclioptions.ConfigFlags) Factory { + matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags) + f := &factoryImpl{ + kubeConfigFlags: kubeConfigFlags, + Factory: cmdutil.NewFactory(matchVersionKubeConfigFlags), + } + return f +} + +// KarmadaClientSet returns a karmada clientset +func (f *factoryImpl) KarmadaClientSet() (karmadaclientset.Interface, error) { + clientConfig, err := f.ToRESTConfig() + if err != nil { + return nil, err + } + return karmadaclientset.NewForConfig(clientConfig) +} + +// FacotryForMemberCluster returns a cmdutil.Factory for the member cluster +func (f *factoryImpl) FactoryForMemberCluster(clusterName string) (cmdutil.Factory, error) { + // Get client config of the karmada, and use it to create a cmdutil.Factory for the member cluster later. + clientConfig, err := f.ToRESTConfig() + if err != nil { + return nil, err + } + karmadaAPIServer := clientConfig.Host + + // Check if the given cluster is joined to karmada + client, err := karmadaclientset.NewForConfig(clientConfig) + if err != nil { + return nil, err + } + _, err = client.ClusterV1alpha1().Clusters().Get(context.TODO(), clusterName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + // Inherit all properties from the original flags specified by user except for the kube-apiserver address. + kubeConfigFlags := &genericclioptions.ConfigFlags{ + CacheDir: f.kubeConfigFlags.CacheDir, + KubeConfig: f.kubeConfigFlags.KubeConfig, + ClusterName: f.kubeConfigFlags.ClusterName, + AuthInfoName: f.kubeConfigFlags.AuthInfoName, + Context: f.kubeConfigFlags.Context, + Namespace: f.kubeConfigFlags.Namespace, + Insecure: f.kubeConfigFlags.Insecure, + CertFile: f.kubeConfigFlags.CertFile, + KeyFile: f.kubeConfigFlags.KeyFile, + CAFile: f.kubeConfigFlags.CAFile, + BearerToken: f.kubeConfigFlags.BearerToken, + Impersonate: f.kubeConfigFlags.Impersonate, + ImpersonateUID: f.kubeConfigFlags.ImpersonateUID, + ImpersonateGroup: f.kubeConfigFlags.ImpersonateGroup, + Username: f.kubeConfigFlags.Username, + Password: f.kubeConfigFlags.Password, + Timeout: f.kubeConfigFlags.Timeout, + WrapConfigFn: f.kubeConfigFlags.WrapConfigFn, + } + // Override the kube-apiserver address. + memberAPIserver := karmadaAPIServer + fmt.Sprintf(proxyURL, clusterName) + kubeConfigFlags.APIServer = &memberAPIserver + matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags) + return cmdutil.NewFactory(matchVersionKubeConfigFlags), nil +}