Untitled
unknown
plain_text
a year ago
3.4 kB
13
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"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"os"
"path/filepath"
)
func (f *KubeClientFactory) setupOIDCAuth(config *rest.Config, kubeconfig *clientcmdapi.Config) error {
// Get token from environment variable first
if token := os.Getenv("KUBE_TOKEN"); token != "" {
config.BearerToken = token
return nil
}
// Get current context and auth info
currentContext := kubeconfig.CurrentContext
context := kubeconfig.Contexts[currentContext]
if context == nil {
return fmt.Errorf("current context not found: %s", currentContext)
}
authInfo := kubeconfig.AuthInfos[context.AuthInfo]
if authInfo == nil {
return fmt.Errorf("auth info not found for user: %s", context.AuthInfo)
}
// Handle OIDC auth provider
if authInfo.AuthProvider != nil && authInfo.AuthProvider.Name == "oidc" {
if authInfo.AuthProvider.Config == nil {
return fmt.Errorf("oidc auth provider config is nil")
}
// Use id-token if available
if idToken, ok := authInfo.AuthProvider.Config["id-token"]; ok && idToken != "" {
config.BearerToken = idToken
return nil
}
// Use refresh token if available
if refreshToken, ok := authInfo.AuthProvider.Config["refresh-token"]; ok && refreshToken != "" {
// TODO: Implement token refresh logic if needed
return fmt.Errorf("token refresh not implemented")
}
}
// Fallback to direct token or token file
if authInfo.Token != "" {
config.BearerToken = authInfo.Token
return nil
}
if authInfo.TokenFile != "" {
tokenBytes, err := os.ReadFile(authInfo.TokenFile)
if err != nil {
return fmt.Errorf("failed to read token file: %w", err)
}
config.BearerToken = string(tokenBytes)
return nil
}
return fmt.Errorf("no valid authentication method found")
}
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 {
// Production path construction
kubeconfigPath = filepath.Join(f.kubeconfigBasePath, config.TenantID, config.ClusterID, "kubeconfig")
}
// Load kubeconfig
loadingRules := &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfigPath}
configOverrides := &clientcmd.ConfigOverrides{}
kubeConfig, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
loadingRules,
configOverrides).ClientConfig()
if err != nil {
return nil, fmt.Errorf("failed to load kubeconfig: %w", err)
}
// Load raw kubeconfig for auth setup
rawConfig, err := clientcmd.LoadFromFile(kubeconfigPath)
if err != nil {
return nil, fmt.Errorf("failed to load raw kubeconfig: %w", err)
}
// Setup authentication
if err := f.setupOIDCAuth(kubeConfig, rawConfig); err != nil {
return nil, fmt.Errorf("failed to setup auth: %w", err)
}
// Create 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
}Editor is loading...
Leave a Comment