Untitled

 avatar
unknown
plain_text
a month ago
3.2 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"
    "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 the kubeconfig file
    kubeConfig, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
    if err != nil {
        return nil, fmt.Errorf("failed to load kubeconfig: %w", err)
    }

    // Try to get token from environment first
    if token := os.Getenv("KUBE_TOKEN"); token != "" {
        kubeConfig.BearerToken = token
    } else {
        // Load raw kubeconfig to access auth provider config
        raw, err := clientcmd.LoadFromFile(kubeconfigPath)
        if err != nil {
            return nil, fmt.Errorf("failed to load raw kubeconfig: %w", err)
        }

        // Get current context and user
        currentContext := raw.CurrentContext
        context := raw.Contexts[currentContext]
        if context == nil {
            return nil, fmt.Errorf("current context not found: %s", currentContext)
        }

        authInfo := raw.AuthInfos[context.AuthInfo]
        if authInfo == nil {
            return nil, fmt.Errorf("auth info not found for user: %s", context.AuthInfo)
        }

        // Handle OIDC authentication
        if authInfo.AuthProvider != nil && authInfo.AuthProvider.Name == "oidc" {
            if authInfo.AuthProvider.Config != nil {
                // Try id-token first
                if idToken, exists := authInfo.AuthProvider.Config["id-token"]; exists && idToken != "" {
                    kubeConfig.BearerToken = idToken
                }
            }
        } else if authInfo.Token != "" {
            // Fall back to static token if present
            kubeConfig.BearerToken = authInfo.Token
        }
    }

    // Ensure we have a token
    if kubeConfig.BearerToken == "" {
        return nil, fmt.Errorf("no valid authentication token found")
    }

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

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

    return NewKubeClientImpl(clientset, dynamicClient, &config), nil
}
Leave a Comment