Files
Go.Rig-Operator/deploy/rig-operator/internal/provider/harvester/strategy.go
2026-01-15 09:58:01 +00:00

141 lines
3.7 KiB
Go

package harvester
import (
"context"
"fmt"
"vanderlande.com/ittp/appstack/rig-operator/api/v1alpha1"
template "vanderlande.com/ittp/appstack/rig-operator/internal/templates/harvester"
)
// harvesterNodePool matches the exact JSON structure required by the Helm Chart
type harvesterNodePool struct {
Name string `json:"name"`
DisplayName string `json:"displayName"`
Quantity int `json:"quantity"`
Etcd bool `json:"etcd"`
ControlPlane bool `json:"controlplane"`
Worker bool `json:"worker"`
Paused bool `json:"paused"`
// Harvester Specific Fields
CpuCount int `json:"cpuCount"`
MemorySize int `json:"memorySize"` // GB
DiskSize int `json:"diskSize"` // GB
ImageName string `json:"imageName"`
NetworkName string `json:"networkName"`
SshUser string `json:"sshUser"`
VmNamespace string `json:"vmNamespace"`
UserData string `json:"userData"`
}
type Strategy struct {
blueprint *v1alpha1.HarvesterBlueprint
userData string
rancherURL string
defaults template.Defaults
}
// NewStrategy initializes the strategy with defaults and optional overrides
func NewStrategy(hbp *v1alpha1.HarvesterBlueprint, infraUserData string, infraRancherURL string, defaults template.Defaults) *Strategy { // 1. Determine UserData priority: Infra (IBP) > Template Default
finalUserData := infraUserData
if finalUserData == "" {
finalUserData = defaults.UserData
}
return &Strategy{
blueprint: hbp,
userData: finalUserData,
rancherURL: infraRancherURL,
defaults: defaults,
}
}
// GenerateNodePools implements provider.Strategy
func (s *Strategy) GenerateNodePools(ctx context.Context, cbp *v1alpha1.ClusterBlueprint) (interface{}, error) {
var pools []interface{}
// Helper to map generic req -> harvester specific struct
mapPool := func(name string, qty, cpu, memGB, diskGB int, isEtcd, isCp, isWk bool) harvesterNodePool {
return harvesterNodePool{
Name: name,
DisplayName: name,
Quantity: qty,
Etcd: isEtcd,
ControlPlane: isCp,
Worker: isWk,
Paused: false,
// Mapping: Generic (GB) -> Harvester (GB) [No conversion needed]
CpuCount: cpu,
MemorySize: memGB,
DiskSize: diskGB,
// Harvester Specifics from HBP
ImageName: s.blueprint.Spec.ImageName,
NetworkName: s.blueprint.Spec.NetworkName,
SshUser: s.blueprint.Spec.SshUser,
VmNamespace: s.blueprint.Spec.VmNamespace,
UserData: s.userData,
}
}
// 1. Control Plane Pool
cpQty := 1
if cbp.Spec.ControlPlaneHA {
cpQty = 3
}
// Use Defaults from YAML for CP sizing
pools = append(pools, mapPool(
"cp-pool",
cpQty,
s.defaults.CP_CPU,
s.defaults.CP_Mem,
s.defaults.CP_Disk,
true, true, false,
))
// 2. Worker Pools
for _, wp := range cbp.Spec.WorkerPools {
pools = append(pools, mapPool(
wp.Name,
wp.Quantity,
wp.CpuCores,
wp.MemoryGB,
wp.DiskGB,
false, false, true,
))
}
return pools, nil
}
// GetGlobalOverrides implements provider.Strategy
func (s *Strategy) GetGlobalOverrides(ctx context.Context, cbp *v1alpha1.ClusterBlueprint, credentialSecretName string) (map[string]interface{}, error) {
// secret://<namespace>:<secretName>
secretURI := fmt.Sprintf("secret://%s:%s", cbp.Namespace, credentialSecretName)
overrides := map[string]interface{}{
"cloud_provider_name": "harvester",
"cloud_provider_config": secretURI,
// Inject Rancher URL
"rancher": map[string]interface{}{
"cattle": map[string]interface{}{
"url": s.rancherURL,
},
},
"chartValues": map[string]interface{}{
"harvester-cloud-provider": map[string]interface{}{
"global": map[string]interface{}{
"cattle": map[string]interface{}{
"clusterName": cbp.Name,
},
},
},
},
}
return overrides, nil
}