Untitled

 avatar
unknown
plain_text
a month ago
3.3 kB
6
Indexable
package handlers

import (
    "fmt"
    "k8s.io/client-go/dynamic"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/tools/clientcmd/api"
    _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"  // Import OIDC auth plugin
    "os"
    "path/filepath"
)

type ClientConfig struct {
    ClusterID       string
    TenantID        string
    Namespace       string
    BearerAuthToken string
}

type KubeClientFactoryInterface interface {
    GetClient(config ClientConfig) (KubeClient, error)
}

type KubeClientFactory struct {
    kubeconfigBasePath string
}

func NewKubeClientFactory(kubeconfigBasePath string) KubeClientFactoryInterface {
    return &KubeClientFactory{
        kubeconfigBasePath: kubeconfigBasePath,
    }
}

func (f *KubeClientFactory) GetClient(config ClientConfig) (KubeClient, error) {
    var kubeconfigPath string

    // For testing environment
    if config.ClusterID == "default" {
        kubeconfigPath = filepath.Join(f.kubeconfigBasePath, "kubeconfig")
    } else {
        kubeconfigPath = filepath.Join(f.kubeconfigBasePath, config.TenantID, config.ClusterID, "kubeconfig")
    }

    // Load raw kubeconfig first
    configLoader := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
        &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfigPath},
        &clientcmd.ConfigOverrides{},
    )

    rawConfig, err := configLoader.RawConfig()
    if err != nil {
        return nil, fmt.Errorf("failed to load raw kubeconfig: %w", err)
    }

    // Get current context
    contextName := rawConfig.CurrentContext
    if contextName == "" {
        return nil, fmt.Errorf("no current context found in kubeconfig")
    }

    context, exists := rawConfig.Contexts[contextName]
    if !exists {
        return nil, fmt.Errorf("context %s not found in kubeconfig", contextName)
    }

    // Get authentication info
    authInfo, exists := rawConfig.AuthInfos[context.AuthInfo]
    if !exists {
        return nil, fmt.Errorf("auth info %s not found in kubeconfig", context.AuthInfo)
    }

    // Build rest.Config
    restConfig, err := configLoader.ClientConfig()
    if err != nil {
        return nil, fmt.Errorf("failed to create REST config: %w", err)
    }

    // Handle auth token priority:
    // 1. Environment variable
    // 2. Auth provider token
    // 3. Static token
    if token := os.Getenv("KUBE_TOKEN"); token != "" {
        restConfig.BearerToken = token
    } else if authInfo.AuthProvider != nil {
        if authInfo.AuthProvider.Config != nil {
            if idToken, exists := authInfo.AuthProvider.Config["id-token"]; exists && idToken != "" {
                restConfig.BearerToken = idToken
            }
        }
    } else if authInfo.Token != "" {
        restConfig.BearerToken = authInfo.Token
    }

    // Create the clientset
    clientset, err := kubernetes.NewForConfig(restConfig)
    if err != nil {
        return nil, fmt.Errorf("failed to create clientset: %w", err)
    }

    // Create dynamic client
    dynamicClient, err := dynamic.NewForConfig(restConfig)
    if err != nil {
        return nil, fmt.Errorf("failed to create dynamic client: %w", err)
    }

    return NewKubeClientImpl(clientset, dynamicClient, &config), nil
}
Editor is loading...
Leave a Comment