@@ -19,6 +19,7 @@ package e2e
19
19
import (
20
20
"context"
21
21
"encoding/base64"
22
+ "errors"
22
23
"fmt"
23
24
"os"
24
25
"path/filepath"
@@ -58,6 +59,11 @@ const (
58
59
InvalidWorkerOfferingName = "CLOUDSTACK_INVALID_WORKER_MACHINE_OFFERING"
59
60
)
60
61
62
+ const (
63
+ ControlPlaneIndicator = "control-plane"
64
+ MachineDeploymentIndicator = "md"
65
+ )
66
+
61
67
type CommonSpecInput struct {
62
68
E2EConfig * clusterctl.E2EConfig
63
69
ClusterctlConfigPath string
@@ -191,23 +197,7 @@ type cloudConfig struct {
191
197
}
192
198
193
199
func DestroyOneMachine (clusterName string , machineType string ) {
194
- encodedSecret := os .Getenv ("CLOUDSTACK_B64ENCODED_SECRET" )
195
- secret , err := base64 .StdEncoding .DecodeString (encodedSecret )
196
- if err != nil {
197
- Fail ("Failed " )
198
- }
199
- cfg := & cloudConfig {VerifySSL : true }
200
- if rawCfg , err := ini .Load (secret ); err != nil {
201
- Fail ("Failed to load INI file" )
202
- } else if g := rawCfg .Section ("Global" ); len (g .Keys ()) == 0 {
203
- Fail ("Global section not found" )
204
- } else if err = rawCfg .Section ("Global" ).StrictMapTo (cfg ); err != nil {
205
- Fail ("Error encountered while parsing Global section" )
206
- }
207
-
208
- By ("Creating a CloudStack client" )
209
- client := cloudstack .NewAsyncClient (cfg .APIURL , cfg .APIKey , cfg .SecretKey , cfg .VerifySSL )
210
-
200
+ client := createCloudStackClient ()
211
201
matcher := clusterName + "-" + machineType
212
202
213
203
Byf ("Listing machines with %q" , matcher )
@@ -241,33 +231,41 @@ func DestroyOneMachine(clusterName string, machineType string) {
241
231
}
242
232
}
243
233
244
- func CheckAffinityGroup (clusterName string , affinityType string ) {
245
- encodedSecret := os .Getenv ("CLOUDSTACK_B64ENCODED_SECRET" )
246
- secret , err := base64 .StdEncoding .DecodeString (encodedSecret )
247
- if err != nil {
248
- Fail ("Failed " )
249
- }
250
- cfg := & cloudConfig {VerifySSL : true }
251
- if rawCfg , err := ini .Load (secret ); err != nil {
252
- Fail ("Failed to load INI file" )
253
- } else if g := rawCfg .Section ("Global" ); len (g .Keys ()) == 0 {
254
- Fail ("Global section not found" )
255
- } else if err = rawCfg .Section ("Global" ).StrictMapTo (cfg ); err != nil {
256
- Fail ("Error encountered while parsing Global section" )
234
+ func CheckAffinityGroupsDeleted (affinityIds []string ) error {
235
+ client := createCloudStackClient ()
236
+
237
+ for _ , affinityId := range affinityIds {
238
+ affinity , count , _ := client .AffinityGroup .GetAffinityGroupByID (affinityId )
239
+ if count > 0 {
240
+ return errors .New ("Affinity group " + affinity .Name + " still exists" )
241
+ }
257
242
}
243
+ return nil
244
+ }
258
245
259
- By ( "Creating a CloudStack client" )
260
- client := cloudstack . NewAsyncClient ( cfg . APIURL , cfg . APIKey , cfg . SecretKey , cfg . VerifySSL )
246
+ func CheckAffinityGroup ( clusterName string , affinityType string ) [] string {
247
+ client := createCloudStackClient ( )
261
248
262
249
By ("Listing all machines" )
263
250
listResp , err := client .VirtualMachine .ListVirtualMachines (client .VirtualMachine .NewListVirtualMachinesParams ())
264
251
if err != nil {
265
252
Fail ("Failed to list machines" )
266
253
}
267
254
affinityTypeString := strings .Title (fmt .Sprintf ("%sAffinity" , affinityType ))
255
+ cpHostIdSet := make (map [string ]bool )
256
+ mdHostIdSet := make (map [string ]bool )
257
+ affinityIds := []string {}
258
+
268
259
for _ , vm := range listResp .VirtualMachines {
269
260
if strings .Contains (vm .Name , clusterName ) {
261
+ By (vm .Name + " is in host " + vm .Hostname + " (" + vm .Hostid + ")" )
262
+ err := checkVMHostAssignments (vm , cpHostIdSet , mdHostIdSet , affinityType )
263
+ if err != nil {
264
+ Fail (err .Error ())
265
+ }
266
+
270
267
for _ , affinity := range vm .Affinitygroup {
268
+ affinityIds = append (affinityIds , affinity .Id )
271
269
affinity , _ , _ := client .AffinityGroup .GetAffinityGroupByID (affinity .Id )
272
270
if err != nil {
273
271
Fail ("Failed to get affinity group for " + affinity .Id )
@@ -284,6 +282,55 @@ func CheckAffinityGroup(clusterName string, affinityType string) {
284
282
}
285
283
}
286
284
}
285
+ return affinityIds
286
+ }
287
+
288
+ func createCloudStackClient () * cloudstack.CloudStackClient {
289
+ encodedSecret := os .Getenv ("CLOUDSTACK_B64ENCODED_SECRET" )
290
+ secret , err := base64 .StdEncoding .DecodeString (encodedSecret )
291
+ if err != nil {
292
+ Fail ("Failed " )
293
+ }
294
+ cfg := & cloudConfig {VerifySSL : true }
295
+ if rawCfg , err := ini .Load (secret ); err != nil {
296
+ Fail ("Failed to load INI file" )
297
+ } else if g := rawCfg .Section ("Global" ); len (g .Keys ()) == 0 {
298
+ Fail ("Global section not found" )
299
+ } else if err = rawCfg .Section ("Global" ).StrictMapTo (cfg ); err != nil {
300
+ Fail ("Error encountered while parsing Global section" )
301
+ }
302
+
303
+ By ("Creating a CloudStack client" )
304
+ client := cloudstack .NewAsyncClient (cfg .APIURL , cfg .APIKey , cfg .SecretKey , cfg .VerifySSL )
305
+ return client
306
+ }
307
+
308
+ func checkVMHostAssignments (vm * cloudstack.VirtualMachine , cpHostIdSet map [string ]bool , mdHostIdSet map [string ]bool , affinityType string ) error {
309
+ if strings .Contains (vm .Name , ControlPlaneIndicator ) {
310
+ if len (cpHostIdSet ) > 0 {
311
+ _ , ok := cpHostIdSet [vm .Hostid ]
312
+ if affinityType == "pro" && ! ok {
313
+ return errors .New (vm .Name + " is deployed in a different host: " + vm .Hostname + " when affinity type is " + affinityType )
314
+ }
315
+ if affinityType == "anti" && ok {
316
+ return errors .New (vm .Name + " is deployed in the same host: " + vm .Hostname + " when affinity type is " + affinityType )
317
+ }
318
+ }
319
+ cpHostIdSet [vm .Hostid ] = true
320
+ }
321
+ if strings .Contains (vm .Name , MachineDeploymentIndicator ) {
322
+ if len (mdHostIdSet ) > 0 {
323
+ _ , ok := mdHostIdSet [vm .Hostid ]
324
+ if affinityType == "pro" && ! ok {
325
+ return errors .New (vm .Name + " is deployed in a different host: " + vm .Hostname + " when affinity type is " + affinityType )
326
+ }
327
+ if affinityType == "anti" && ok {
328
+ return errors .New (vm .Name + " is deployed in the same host: " + vm .Hostname + " when affinity type is " + affinityType )
329
+ }
330
+ }
331
+ mdHostIdSet [vm .Hostid ] = true
332
+ }
333
+ return nil
287
334
}
288
335
289
336
func WaitForMachineRemediationAfterDestroy (ctx context.Context , proxy framework.ClusterProxy , cluster * clusterv1.Cluster , machineMatcher string , healthyMachineCount int , intervals []interface {}) {
0 commit comments