Files

139 lines
4.0 KiB
Go
Raw Permalink Normal View History

2026-01-15 09:58:01 +00:00
package vsphere
import (
"context"
rigv1 "vanderlande.com/ittp/appstack/rig-operator/api/v1alpha1"
vspheretpl "vanderlande.com/ittp/appstack/rig-operator/internal/templates/vsphere"
)
type Strategy struct {
blueprint *rigv1.VsphereBlueprint
userData string
rancherURL string
defaults vspheretpl.Defaults
}
// NewStrategy creates the vSphere logic handler
func NewStrategy(vbp *rigv1.VsphereBlueprint, userData string, rancherURL string, defaults vspheretpl.Defaults) *Strategy {
// 1. Resolve UserData (Infra > Template Default)
finalUserData := userData
if finalUserData == "" {
finalUserData = defaults.UserData
}
return &Strategy{
blueprint: vbp,
userData: finalUserData,
rancherURL: rancherURL,
defaults: defaults,
}
}
// GenerateNodePools maps the generic ClusterBlueprint to vSphere-specific NodePool maps
func (s *Strategy) GenerateNodePools(ctx context.Context, cbp *rigv1.ClusterBlueprint) (interface{}, error) {
var nodePools []map[string]interface{}
// 1. Control Plane Node Pool
// We rely on the defaults extracted from values.yaml (e.g. 4 Core, 8GB)
// vSphere Chart expects MB, so we multiply GB * 1024.
cpQty := 1
if cbp.Spec.ControlPlaneHA {
cpQty = 3
}
nodePools = append(nodePools, s.buildPool(
"control-plane-nodes", // Name
"cp-nodes", // Display Name
cpQty, // Quantity
s.defaults.CP_CPU, // Cores
s.defaults.CP_Mem*1024, // RAM (GB -> MB)
s.defaults.CP_Disk*1024, // Disk (GB -> MB)
true, // Etcd
true, // ControlPlane
false, // Worker
))
// 2. Worker Pools
// We iterate over the user's requested pools in the CBP
for _, wp := range cbp.Spec.WorkerPools {
nodePools = append(nodePools, s.buildPool(
wp.Name,
wp.Name,
wp.Quantity,
wp.CpuCores,
wp.MemoryGB*1024, // Convert GB to MB
wp.DiskGB*1024, // Convert GB to MB
false, // Etcd
false, // ControlPlane
true, // Worker
))
}
return nodePools, nil
}
// GetGlobalOverrides injects the vSphere-specific global values (Cloud Provider, Credentials, URLs)
func (s *Strategy) GetGlobalOverrides(ctx context.Context, cbp *rigv1.ClusterBlueprint, credentialSecret string) (map[string]interface{}, error) {
overrides := map[string]interface{}{
// Tell Helm we are on vSphere
"cloudprovider": "vsphere",
// The Secret containing username/password/vcenter-address
"cloudCredentialSecretName": credentialSecret,
// Register with the correct Rancher Manager
"rancher": map[string]interface{}{
"cattle": map[string]interface{}{
"url": s.rancherURL,
},
},
// Cluster Metadata
"cluster": map[string]interface{}{
"name": cbp.Name,
"config": map[string]interface{}{
"kubernetesVersion": cbp.Spec.KubernetesVersion,
},
},
}
return overrides, nil
}
// buildPool is a private helper to construct the exact map structure the vSphere Helm Chart expects
func (s *Strategy) buildPool(name, displayName string, qty, cpu, ramMB, diskMB int, etcd, cp, worker bool) map[string]interface{} {
pool := map[string]interface{}{
// Generic RKE2 Node Settings
"name": name,
"displayName": displayName,
"quantity": qty,
"etcd": etcd,
"controlplane": cp,
"worker": worker,
"paused": false,
// vSphere Infrastructure Location (From Blueprint)
"vcenter": s.blueprint.Spec.VCenter,
"datacenter": s.blueprint.Spec.Datacenter,
"folder": s.blueprint.Spec.Folder,
"pool": s.blueprint.Spec.ResourcePool,
"datastoreCluster": s.blueprint.Spec.Datastore, // Assumes chart supports this key. If not, use "datastore".
"network": []string{s.blueprint.Spec.Network},
// Cloning Details
"creationType": "template",
"cloneFrom": s.blueprint.Spec.Template,
// Hardware Sizing (Already converted to MB)
"cpuCount": cpu,
"memorySize": ramMB,
"diskSize": diskMB,
// Cloud Init
"cloudConfig": s.userData,
}
return pool
}