...

Source file src/edge-infra.dev/pkg/edge/api/services/gke_client.go

Documentation: edge-infra.dev/pkg/edge/api/services

     1  package services
     2  
     3  import (
     4  	"context"
     5  	b64 "encoding/base64"
     6  	"errors"
     7  	"fmt"
     8  
     9  	clusterApi "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/container/v1beta1"
    10  	iamv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/iam/v1beta1"
    11  	resourceApi "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/resourcemanager/v1beta1"
    12  	helmApi "github.com/fluxcd/helm-controller/api/v2"
    13  	helmRepositoryApi "github.com/fluxcd/source-controller/api/v1"
    14  
    15  	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    16  	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
    17  	"k8s.io/client-go/kubernetes/scheme"
    18  	"k8s.io/client-go/rest"
    19  	"k8s.io/client-go/tools/clientcmd/api"
    20  	"sigs.k8s.io/controller-runtime/pkg/client"
    21  
    22  	"edge-infra.dev/pkg/edge/api/types"
    23  	"edge-infra.dev/pkg/edge/api/utils"
    24  
    25  	bannerAPI "edge-infra.dev/pkg/edge/apis/banner/v1alpha1"
    26  	edgeCluster "edge-infra.dev/pkg/edge/apis/cluster/v1alpha1"
    27  	gkeClusterApi "edge-infra.dev/pkg/edge/apis/gkecluster/v1alpha1"
    28  )
    29  
    30  func init() {
    31  	utilruntime.Must(edgeCluster.AddToScheme(scheme.Scheme))
    32  	utilruntime.Must(resourceApi.AddToScheme(scheme.Scheme))
    33  	utilruntime.Must(helmApi.AddToScheme(scheme.Scheme))
    34  	utilruntime.Must(helmRepositoryApi.AddToScheme(scheme.Scheme))
    35  	utilruntime.Must(clusterApi.AddToScheme(scheme.Scheme))
    36  	utilruntime.Must(apiextensionsv1.AddToScheme(scheme.Scheme))
    37  	utilruntime.Must(bannerAPI.AddToScheme(scheme.Scheme))
    38  	utilruntime.Must(clusterApi.AddToScheme(scheme.Scheme))
    39  	utilruntime.Must(gkeClusterApi.AddToScheme(scheme.Scheme))
    40  
    41  	utilruntime.Must(iamv1beta1.AddToScheme(scheme.Scheme))
    42  }
    43  
    44  //go:generate mockgen -destination=../mocks/mock_gke_client.go -package=mocks edge-infra.dev/pkg/edge/api/services GkeClient
    45  type GkeClient interface {
    46  	GetConfigForCluster(ctx context.Context, cluster *types.GkeCluster) (*rest.Config, error)
    47  	GetRuntimeClient(ctx context.Context, cluster *types.GkeCluster) (client.WithWatch, error)
    48  }
    49  
    50  type gkeClient struct {
    51  	// configs
    52  	KubeConfig *rest.Config
    53  
    54  	// clients
    55  	RuntimeClient client.WithWatch
    56  
    57  	// caches
    58  	RuntimeClientMap map[string]client.WithWatch
    59  }
    60  
    61  func (gke *gkeClient) GetClientName(cluster *types.GkeCluster) string {
    62  	return fmt.Sprintf("%s-%s", cluster.Banner, cluster.Name)
    63  }
    64  
    65  func (gke *gkeClient) GetConfigForCluster(ctx context.Context, cluster *types.GkeCluster) (*rest.Config, error) {
    66  	singleResp := &clusterApi.ContainerCluster{}
    67  	key := client.ObjectKey{Namespace: cluster.Banner, Name: cluster.Name}
    68  	if err := gke.RuntimeClient.Get(ctx, key, singleResp); err != nil {
    69  		return nil, err
    70  	}
    71  	return getConfigForCluster(singleResp)
    72  }
    73  
    74  func getConfigForCluster(singleResp *clusterApi.ContainerCluster) (*rest.Config, error) {
    75  	if singleResp.Spec.MasterAuth == nil || singleResp.Spec.MasterAuth.ClusterCaCertificate == nil {
    76  		return nil, errors.New("ClusterCaCertificate not ready on kcc container cluster")
    77  	}
    78  	if singleResp.Status.Endpoint == nil {
    79  		return nil, errors.New("host not ready on kcc container cluster")
    80  	}
    81  	sDec, err := b64.StdEncoding.DecodeString(*singleResp.Spec.MasterAuth.ClusterCaCertificate)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  	config := &rest.Config{
    86  		TLSClientConfig: rest.TLSClientConfig{
    87  			CAData: sDec,
    88  		},
    89  
    90  		Host: *singleResp.Status.Endpoint,
    91  		AuthProvider: &api.AuthProviderConfig{
    92  			Name: "gcp",
    93  		},
    94  	}
    95  	return config, nil
    96  }
    97  
    98  func (gke *gkeClient) GetRuntimeClient(ctx context.Context, cluster *types.GkeCluster) (client.WithWatch, error) {
    99  	if cluster == nil {
   100  		return gke.RuntimeClient, nil
   101  	}
   102  	name := gke.GetClientName(cluster)
   103  	if client, ok := gke.RuntimeClientMap[name]; ok {
   104  		return client, nil
   105  	}
   106  	cfg, err := gke.GetConfigForCluster(ctx, cluster)
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  	runtimeClient, err := client.NewWithWatch(cfg, client.Options{Scheme: scheme.Scheme})
   111  	if err != nil {
   112  		return nil, err
   113  	}
   114  	gke.RuntimeClientMap[name] = runtimeClient
   115  	return runtimeClient, nil
   116  }
   117  
   118  func NewGkeClient(masterconfig string) (*gkeClient, error) { //nolint stupid
   119  	var err error
   120  	var config *rest.Config
   121  	var runtimeClient client.WithWatch
   122  
   123  	if masterconfig != "" {
   124  		if config, err = utils.GetKubeConfig(masterconfig); err != nil {
   125  			return nil, err
   126  		}
   127  		if runtimeClient, err = client.NewWithWatch(config, client.Options{Scheme: scheme.Scheme}); err != nil {
   128  			return nil, err
   129  		}
   130  	}
   131  	return &gkeClient{
   132  		KubeConfig:       config,
   133  		RuntimeClient:    runtimeClient,
   134  		RuntimeClientMap: map[string]client.WithWatch{},
   135  	}, nil
   136  }
   137  

View as plain text