-
Notifications
You must be signed in to change notification settings - Fork 286
/
multi_template.go
143 lines (126 loc) Β· 6.02 KB
/
multi_template.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package framework
import (
"context"
"fmt"
"strings"
"testing"
vspherev1 "sigs.k8s.io/cluster-api-provider-vsphere/api/v1beta1"
"github.com/aws/eks-anywhere/pkg/api/v1alpha1"
"github.com/aws/eks-anywhere/pkg/logger"
)
const (
// VSphereMultiTemplateUbuntu127 is to test multiple vSphere templates.
VSphereMultiTemplateUbuntu127 = "T_VSPHERE_TEMPLATE_UBUNTU_2204_1_27"
// ControlPlaneMachineLabel is to get control plane vSphere machines from machine list.
ControlPlaneMachineLabel = "cluster.x-k8s.io/control-plane"
// EtcdMachineLabel is to get etcd vSphere machines from machine list.
EtcdMachineLabel = "cluster.x-k8s.io/etcd-cluster"
// workerMachineLabel is to get worker vSphere machines from machine list.
workerMachineLabel = "cluster.x-k8s.io/deployment-name"
)
// VSphereMultiTemplateUbuntu127RequiredEnvVars is required for TestVSphereMultipleTemplatesUbuntu127.
var VSphereMultiTemplateUbuntu127RequiredEnvVars = []string{
VSphereMultiTemplateUbuntu127,
}
// RequiredVsphereMultiTemplateUbuntu127EnvVars return required env vars for TestVSphereMultipleTemplatesUbuntu127.
func RequiredVsphereMultiTemplateUbuntu127EnvVars() []string {
return VSphereMultiTemplateUbuntu127RequiredEnvVars
}
// CheckVsphereMultiTemplateUbuntu127EnvVars checks is required env vars are present.
func CheckVsphereMultiTemplateUbuntu127EnvVars(t *testing.T) {
checkRequiredEnvVars(t, VSphereMultiTemplateUbuntu127RequiredEnvVars)
}
// VsphereMachineValidation should return an error if either an error is encountered during execution or the validation logically fails.
// This validation function will be executed by ValidateVsphereMachine and ValidateWorkerNodeVsphereMachine
// with a vSphere machine config and a corresponding vSphere machine.
type VsphereMachineValidation func(machineConfig *v1alpha1.VSphereMachineConfig, machine vspherev1.VSphereMachine) (err error)
// ValidateVsphereMachine deduces the control plane or etcd configuration to machine mapping
// and for each configuration/machine pair executes the provided validation functions.
func (e *ClusterE2ETest) ValidateVsphereMachine(selector string, machineConfig *v1alpha1.VSphereMachineConfig, validations ...VsphereMachineValidation) {
e.T.Log("Validating VSphere machine template")
ctx := context.Background()
machines, err := e.KubectlClient.GetVsphereMachine(ctx, e.Cluster().KubeconfigFile, selector)
if err != nil {
e.T.Fatal(err)
}
for _, machine := range machines {
for _, validation := range validations {
err = validation(machineConfig, machine)
if err != nil {
e.T.Errorf("VSphere machine %v is not valid: %v", machine.Name, err)
}
}
}
e.StopIfFailed()
}
// ValidateWorkerNodeVsphereMachine deduces the worker node group configuration to machine mapping
// and for each configuration/machine pair executes the provided validation functions.
func (e *ClusterE2ETest) ValidateWorkerNodeVsphereMachine(validations ...VsphereMachineValidation) {
e.T.Log("Validating VSphere worker machine template")
machineConfigToMachines := e.getMachineConfigToMachine()
for machineConfig, machines := range machineConfigToMachines {
for _, validation := range validations {
for _, machine := range machines {
err := validation(machineConfig, machine)
if err != nil {
e.T.Errorf("VSphere machine %v is not valid: %v", machine.Name, err)
}
}
}
}
e.StopIfFailed()
}
func (e *ClusterE2ETest) getMachineConfigToMachine() map[*v1alpha1.VSphereMachineConfig][]vspherev1.VSphereMachine {
ctx := context.Background()
machines, err := e.KubectlClient.GetVsphereMachine(ctx, e.Cluster().KubeconfigFile, workerMachineLabel)
if err != nil {
e.T.Fatal(err)
}
wngNameToWng := getWngNameToWng(e.ClusterConfig.Cluster.Spec.WorkerNodeGroupConfigurations)
machineConfigToMachine := make(map[*v1alpha1.VSphereMachineConfig][]vspherev1.VSphereMachine)
for _, machine := range machines {
if strings.Contains(machine.GetName(), "control-plane") || strings.Contains(machine.Name, "etcd") {
continue
}
if !strings.HasPrefix(machine.GetName(), e.ClusterName) {
continue
}
wngName, err := getWngNameFromMachine(machine.GetName(), e.ClusterName)
if err != nil {
e.T.Fatal(err)
}
machineConfigName := wngNameToWng[wngName].MachineGroupRef.Name
machineConfig := e.ClusterConfig.VSphereMachineConfigs[machineConfigName]
if _, exists := machineConfigToMachine[machineConfig]; !exists {
machineConfigToMachine[machineConfig] = []vspherev1.VSphereMachine{machine}
} else {
machineConfigToMachine[machineConfig] = append(machineConfigToMachine[machineConfig], machine)
}
}
return machineConfigToMachine
}
func getWngNameToWng(wngConfigs []v1alpha1.WorkerNodeGroupConfiguration) map[string]v1alpha1.WorkerNodeGroupConfiguration {
wngNameToWng := make(map[string]v1alpha1.WorkerNodeGroupConfiguration)
for _, wng := range wngConfigs {
wngNameToWng[wng.Name] = wng
}
return wngNameToWng
}
// getWngNameFromMachine gets worker node group name from machine name by trimming cluster name prefix and two unix nano time suffix.
func getWngNameFromMachine(machineName string, clusterName string) (string, error) {
trimmedMachineName := strings.TrimPrefix(machineName, clusterName+"-")
wngBaseParts := strings.Split(trimmedMachineName, "-")
if len(wngBaseParts) < 3 {
return "", fmt.Errorf("invalid machine name %v", machineName)
}
return strings.Join(wngBaseParts[:len(wngBaseParts)-2], "-"), nil
}
// ValidateMachineTemplate validates if template configured in machine config matches the vSphere machine.
func ValidateMachineTemplate(machineConfig *v1alpha1.VSphereMachineConfig, machine vspherev1.VSphereMachine) (err error) {
if machineConfig.Spec.Template != machine.Spec.Template {
return fmt.Errorf("template on machine %v does not match; configured template: %v; machine actual template: %v",
machine.Name, machineConfig.Spec.Template, machine.Spec.Template)
}
logger.V(4).Info("expected template is present on the corresponding VSphere machine", "machine", machine.Name, "machine template", machine.Spec.Template, "configuration template", machineConfig.Spec.Template)
return nil
}