141 lines
3.7 KiB
Go
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
|
||
|
|
}
|