build source
This commit is contained in:
commit
ee1fec43ed
4171 changed files with 1351288 additions and 0 deletions
102
internal/k8s/client.go
Normal file
102
internal/k8s/client.go
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
package k8s
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
||||
// Client wraps a Kubernetes clientset with config used for template generation.
|
||||
type Client struct {
|
||||
Clientset kubernetes.Interface
|
||||
Dynamic dynamic.Interface
|
||||
Config Config
|
||||
}
|
||||
|
||||
// Config holds cluster-specific settings for pod template generation.
|
||||
type Config struct {
|
||||
Domain string // e.g. "spinoff.dev"
|
||||
Registry string // e.g. "10.22.0.56:30500"
|
||||
GoldenImage string // e.g. "dev-golden:v2"
|
||||
VPNGatewayNS string // e.g. "claw-system"
|
||||
VPNGatewaySecret string // e.g. "vpn-gateway-secrets"
|
||||
AnthropicKey string // baseroute anthropic key
|
||||
OpenAIKey string // baseroute openai key
|
||||
ForgejoURL string // e.g. "http://forgejo.dev-infra.svc:3000"
|
||||
DevPodAPIURL string // e.g. "http://dev-pod-api.dev-infra.svc:8080"
|
||||
}
|
||||
|
||||
// ConfigFromEnv reads Config from environment variables with defaults.
|
||||
func ConfigFromEnv() Config {
|
||||
return Config{
|
||||
Domain: envOrDefault("DOMAIN", "spinoff.dev"),
|
||||
Registry: envOrDefault("REGISTRY", "10.22.0.56:30500"),
|
||||
GoldenImage: envOrDefault("GOLDEN_IMAGE", "dev-golden:v2"),
|
||||
VPNGatewayNS: envOrDefault("VPN_GATEWAY_NS", "claw-system"),
|
||||
VPNGatewaySecret: envOrDefault("VPN_GATEWAY_SECRET", "vpn-gateway-secrets"),
|
||||
AnthropicKey: os.Getenv("DEFAULT_ANTHROPIC_KEY"),
|
||||
OpenAIKey: os.Getenv("DEFAULT_OPENAI_KEY"),
|
||||
ForgejoURL: envOrDefault("FORGEJO_URL", "http://forgejo.dev-infra.svc:3000"),
|
||||
DevPodAPIURL: envOrDefault("DEV_POD_API_URL", "http://dev-pod-api.dev-infra.svc:8080"),
|
||||
}
|
||||
}
|
||||
|
||||
// NewClient creates a Kubernetes client using in-cluster config,
|
||||
// falling back to kubeconfig for local development.
|
||||
func NewClient(cfg Config) (*Client, error) {
|
||||
restCfg, err := rest.InClusterConfig()
|
||||
if err != nil {
|
||||
slog.Info("in-cluster config not available, falling back to kubeconfig")
|
||||
restCfg, err = kubeconfigFromDefault()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create k8s config: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
clientset, err := kubernetes.NewForConfig(restCfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create k8s clientset: %w", err)
|
||||
}
|
||||
|
||||
dyn, err := dynamic.NewForConfig(restCfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create dynamic client: %w", err)
|
||||
}
|
||||
|
||||
return &Client{
|
||||
Clientset: clientset,
|
||||
Dynamic: dyn,
|
||||
Config: cfg,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewClientWithClientset creates a Client with pre-configured clients (for testing).
|
||||
func NewClientWithClientset(clientset kubernetes.Interface, dyn dynamic.Interface, cfg Config) *Client {
|
||||
return &Client{
|
||||
Clientset: clientset,
|
||||
Dynamic: dyn,
|
||||
Config: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
func kubeconfigFromDefault() (*rest.Config, error) {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get home dir: %w", err)
|
||||
}
|
||||
kubeconfig := filepath.Join(home, ".kube", "config")
|
||||
return clientcmd.BuildConfigFromFlags("", kubeconfig)
|
||||
}
|
||||
|
||||
func envOrDefault(key, fallback string) string {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
return v
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue