Skip to content

Commit 528d4e8

Browse files
diafourRoman Sysoev
andauthored
chore(test): fix command to create generic-for-e2e vmclass (#2393)
* refactor(test): optimize vmc precheck run method - rename defaultVMClassName to requiredVMClassName for clarity - extract defaultClassAnnotation as constant to avoid duplication - refactor loop to single pass through vmclasses - extract getVMClassName helper function to package level - add comments explaining variables purpose Signed-off-by: Ivan Mikheykin <ivan.mikheykin@flant.com> Signed-off-by: Roman Sysoev <roman.sysoev@flant.com> Co-authored-by: Roman Sysoev <roman.sysoev@flant.com>
1 parent cb84114 commit 528d4e8

1 file changed

Lines changed: 71 additions & 40 deletions

File tree

  • test/e2e/internal/precheck

test/e2e/internal/precheck/vmc.go

Lines changed: 71 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package precheck
1919
import (
2020
"context"
2121
"fmt"
22+
"strings"
2223

2324
. "github.com/onsi/ginkgo/v2"
2425
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -29,9 +30,10 @@ import (
2930

3031
const (
3132
vmcModuleCheckEnvName = "VMC_PRECHECK"
32-
defaultVMClassName = "generic-for-e2e"
33+
requiredVMClassName = "generic-for-e2e"
3334

34-
vmClassVersion = "v1alpha3"
35+
vmClassVersion = "v1alpha3"
36+
defaultClassAnnotation = "virtualmachineclass.virtualization.deckhouse.io/is-default-class"
3537
)
3638

3739
// vmcPrecheck implements Precheck interface for VMC/VMClass.
@@ -60,66 +62,95 @@ func (c *vmcPrecheck) Run(ctx context.Context, f *framework.Framework) error {
6062
return fmt.Errorf("%s=no to disable this precheck: list VirtualMachineClasses: %w", vmcModuleCheckEnvName, err)
6163
}
6264

63-
var e2eClass map[string]interface{}
64-
var defaultClass map[string]interface{}
65+
var requiredClass map[string]interface{} // VMClass with requiredVMClassName
66+
var defaultClass map[string]interface{} // VMClass with is-default-class annotation
6567

68+
// Single pass through all VMClasses
6669
for i := range vmClasses.Items {
6770
vmClass := vmClasses.Items[i].Object
68-
name, ok := vmClass["metadata"].(map[string]interface{})["name"].(string)
71+
72+
metadata, ok := vmClass["metadata"].(map[string]interface{})
6973
if !ok {
7074
continue
7175
}
7276

73-
if name == defaultVMClassName {
74-
e2eClass = vmClass
75-
}
76-
77-
// Check for default annotation
78-
metadata, ok := vmClass["metadata"].(map[string]interface{})
77+
name, ok := metadata["name"].(string)
7978
if !ok {
8079
continue
8180
}
81+
82+
// Check if this is the required e2e class
83+
if name == requiredVMClassName {
84+
requiredClass = vmClass
85+
}
86+
87+
// Check for default annotation
8288
annotations, ok := metadata["annotations"].(map[string]interface{})
8389
if !ok {
8490
continue
8591
}
86-
if _, ok := annotations["virtualmachineclass.virtualization.deckhouse.io/is-default-class"]; ok {
92+
if _, isDefault := annotations[defaultClassAnnotation]; isDefault {
8793
defaultClass = vmClass
8894
}
8995
}
9096

91-
// Helper to get name from vmClass
92-
getVMClassName := func(m map[string]interface{}) string {
93-
if m == nil {
94-
return ""
95-
}
96-
metadata, ok := m["metadata"].(map[string]interface{})
97-
if !ok {
98-
return ""
99-
}
100-
name, _ := metadata["name"].(string)
101-
return name
97+
// Check if everything is OK: required class exists AND it is the default
98+
if requiredClass != nil && defaultClass != nil && getVMClassName(defaultClass) == requiredVMClassName {
99+
return nil
102100
}
103101

104-
// Check if default VMClass exists and is correct
105-
switch {
106-
case e2eClass != nil && defaultClass != nil && getVMClassName(defaultClass) == defaultVMClassName:
107-
// OK
108-
case e2eClass != nil && defaultClass != nil:
109-
return fmt.Errorf("%s=no to disable this precheck: cluster has wrong default class %q, e2e tests require %q to be default",
110-
vmcModuleCheckEnvName, getVMClassName(defaultClass), defaultVMClassName)
111-
case e2eClass == nil && defaultClass != nil:
112-
return fmt.Errorf("%s=no to disable this precheck: cluster has wrong default class %q, e2e tests require %q to be default",
113-
vmcModuleCheckEnvName, getVMClassName(defaultClass), defaultVMClassName)
114-
case e2eClass != nil && defaultClass == nil:
115-
return fmt.Errorf("%s=no to disable this precheck: cluster has no default class, e2e tests require %q to be default. Run: kubectl annotate vmclass/%s virtualmachineclass.virtualization.deckhouse.io/is-default-class=true",
116-
vmcModuleCheckEnvName, defaultVMClassName, defaultVMClassName)
117-
case e2eClass == nil && defaultClass == nil:
118-
return fmt.Errorf("%s=no to disable this precheck: cluster has no default class and no %q class. Run: kubectl get vmclass/generic -o json | jq 'del(.status) | .metadata.annotations = {\"virtualmachineclass.virtualization.deckhouse.io/is-default-class\":\"true\"}' | kubectl create -f -",
119-
vmcModuleCheckEnvName, defaultVMClassName)
102+
// Build issues and fix commands
103+
var issues, cmds []string
104+
105+
// Handle default class issue
106+
if defaultClass != nil {
107+
issues = append(issues, fmt.Sprintf("cluster has wrong default vmclass %q", getVMClassName(defaultClass)))
108+
cmds = append(cmds, cmdRemoveDefaultAnnotation(getVMClassName(defaultClass)))
109+
} else {
110+
issues = append(issues, "cluster has no default vmclass")
111+
}
112+
113+
// Handle required class issue
114+
if requiredClass != nil {
115+
// Required class exists but is not default - just need to set annotation
116+
issues = append(issues, fmt.Sprintf("e2e tests require vmclass %q to be default", requiredVMClassName))
117+
cmds = append(cmds, cmdSetDefaultAnnotation(requiredVMClassName))
118+
} else {
119+
// Required class doesn't exist - need to create it
120+
issues = append(issues, fmt.Sprintf("e2e tests require vmclass %q to present and be default", requiredVMClassName))
121+
cmds = append(cmds, cmdCopyGenericAsDefaultClass(requiredVMClassName))
122+
}
123+
124+
return fmt.Errorf("%s=no to disable this precheck. Cluster has issues: %s. Run command to fix: %s",
125+
vmcModuleCheckEnvName,
126+
strings.Join(issues, "; "),
127+
strings.Join(cmds, " && "),
128+
)
129+
}
130+
131+
// getVMClassName extracts name from VMClass object
132+
func getVMClassName(m map[string]interface{}) string {
133+
if m == nil {
134+
return ""
120135
}
136+
metadata, ok := m["metadata"].(map[string]interface{})
137+
if !ok {
138+
return ""
139+
}
140+
name, _ := metadata["name"].(string)
141+
return name
142+
}
143+
144+
func cmdCopyGenericAsDefaultClass(targetVMClassName string) string {
145+
return fmt.Sprintf(`kubectl get vmclass/generic -o json | jq 'del(.status) | del(.metadata) | .metadata = {"name":"%s","annotations":{"virtualmachineclass.virtualization.deckhouse.io/is-default-class":"true"}} ' | kubectl create -f -`, targetVMClassName)
146+
}
147+
148+
func cmdRemoveDefaultAnnotation(targetVMClassName string) string {
149+
return fmt.Sprintf(`kubectl annotate vmclass/%s virtualmachineclass.virtualization.deckhouse.io/is-default-class=-`, targetVMClassName)
150+
}
121151

122-
return nil
152+
func cmdSetDefaultAnnotation(targetVMClassName string) string {
153+
return fmt.Sprintf(`kubectl annotate vmclass/%s virtualmachineclass.virtualization.deckhouse.io/is-default-class=true`, targetVMClassName)
123154
}
124155

125156
// Register VMC precheck as common (runs for all tests).

0 commit comments

Comments
 (0)