Skip to content

Commit 7ee4938

Browse files
authored
chore(api): extend core fraction validation error msg (#1793)
Signed-off-by: Roman Sysoev <roman.sysoev@flant.com>
1 parent 5001dae commit 7ee4938

File tree

1 file changed

+50
-30
lines changed

1 file changed

+50
-30
lines changed

images/virtualization-artifact/pkg/controller/service/size_policy_service.go

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@ import (
2828
"github.com/deckhouse/virtualization/api/core/v1alpha2"
2929
)
3030

31+
var ErrSizingPolicyValidation = errors.New("please check the sizing policy of the virtual machine class or contact the administrator for more information")
32+
3133
type SizePolicyService struct{}
3234

3335
func NewSizePolicyService() *SizePolicyService {
3436
return &SizePolicyService{}
3537
}
3638

3739
func (s *SizePolicyService) CheckVMMatchedSizePolicy(vm *v1alpha2.VirtualMachine, vmClass *v1alpha2.VirtualMachineClass) error {
38-
// check if no sizing policy requirements are set
3940
if vmClass == nil || len(vmClass.Spec.SizingPolicies) == 0 {
4041
return nil
4142
}
@@ -45,14 +46,25 @@ func (s *SizePolicyService) CheckVMMatchedSizePolicy(vm *v1alpha2.VirtualMachine
4546
return NewNoSizingPolicyMatchError(vm.Name, vm.Spec.VirtualMachineClassName)
4647
}
4748

48-
var errorsArray []error
49+
var errs []error
4950

50-
errorsArray = append(errorsArray, validateCoreFraction(vm, sizePolicy)...)
51-
errorsArray = append(errorsArray, validateMemory(vm, sizePolicy)...)
52-
errorsArray = append(errorsArray, validatePerCoreMemory(vm, sizePolicy)...)
51+
err := validateCoreFraction(vm, sizePolicy)
52+
if err != nil {
53+
errs = append(errs, err)
54+
}
5355

54-
if len(errorsArray) > 0 {
55-
return fmt.Errorf("sizing policy validate: %w", errors.Join(errorsArray...))
56+
err = validateMemory(vm, sizePolicy)
57+
if err != nil {
58+
errs = append(errs, err)
59+
}
60+
61+
err = validatePerCoreMemory(vm, sizePolicy)
62+
if err != nil {
63+
errs = append(errs, err)
64+
}
65+
66+
if len(errs) > 0 {
67+
return fmt.Errorf("sizing policy validation has failed: %w: %w", errors.Join(errs...), ErrSizingPolicyValidation)
5668
}
5769

5870
return nil
@@ -72,16 +84,15 @@ func getVMSizePolicy(vm *v1alpha2.VirtualMachine, vmClass *v1alpha2.VirtualMachi
7284
return nil
7385
}
7486

75-
func validateCoreFraction(vm *v1alpha2.VirtualMachine, sp *v1alpha2.SizingPolicy) (errorsArray []error) {
87+
func validateCoreFraction(vm *v1alpha2.VirtualMachine, sp *v1alpha2.SizingPolicy) error {
7688
if len(sp.CoreFractions) == 0 {
77-
return
89+
return nil
7890
}
7991

80-
fractionStr := strings.ReplaceAll(vm.Spec.CPU.CoreFraction, "%", "")
92+
fractionStr, _ := strings.CutSuffix(vm.Spec.CPU.CoreFraction, "%")
8193
fraction, err := strconv.Atoi(fractionStr)
8294
if err != nil {
83-
errorsArray = append(errorsArray, fmt.Errorf("unable to parse CPU core fraction: %w", err))
84-
return
95+
return fmt.Errorf("unable to parse CPU core fraction: %w", err)
8596
}
8697

8798
hasFractionValueInPolicy := false
@@ -92,33 +103,34 @@ func validateCoreFraction(vm *v1alpha2.VirtualMachine, sp *v1alpha2.SizingPolicy
92103
}
93104

94105
if !hasFractionValueInPolicy {
95-
errorsArray = append(errorsArray, fmt.Errorf("VM core fraction value %d is not within the allowed values", fraction))
106+
formattedCoreFractions := formatCoreFractionValues(sp.CoreFractions)
107+
return fmt.Errorf("VM core fraction value %s is not within the allowed values: %v", vm.Spec.CPU.CoreFraction, formattedCoreFractions)
96108
}
97109

98-
return
110+
return nil
99111
}
100112

101-
func validateMemory(vm *v1alpha2.VirtualMachine, sp *v1alpha2.SizingPolicy) (errorsArray []error) {
113+
func validateMemory(vm *v1alpha2.VirtualMachine, sp *v1alpha2.SizingPolicy) error {
102114
if sp.Memory == nil || sp.Memory.Max == nil || sp.Memory.Max.IsZero() {
103-
return
115+
return nil
104116
}
105117

106118
if sp.Memory.Min != nil && vm.Spec.Memory.Size.Cmp(*sp.Memory.Min) == common.CmpLesser {
107-
errorsArray = append(errorsArray, fmt.Errorf(
119+
return fmt.Errorf(
108120
"requested VM memory (%s) is less than the minimum allowed, available range [%s, %s]",
109121
vm.Spec.Memory.Size.String(),
110122
sp.Memory.Min.String(),
111123
sp.Memory.Max.String(),
112-
))
124+
)
113125
}
114126

115127
if vm.Spec.Memory.Size.Cmp(*sp.Memory.Max) == common.CmpGreater {
116-
errorsArray = append(errorsArray, fmt.Errorf(
128+
return fmt.Errorf(
117129
"requested VM memory (%s) exceeds the maximum allowed, available range [%s, %s]",
118130
vm.Spec.Memory.Size.String(),
119131
sp.Memory.Min.String(),
120132
sp.Memory.Max.String(),
121-
))
133+
)
122134
}
123135

124136
if sp.Memory.Step != nil && !sp.Memory.Step.IsZero() {
@@ -128,16 +140,16 @@ func validateMemory(vm *v1alpha2.VirtualMachine, sp *v1alpha2.SizingPolicy) (err
128140
}
129141
err := validateIsQuantized(vm.Spec.Memory.Size, minVal, *sp.Memory.Max, *sp.Memory.Step, "VM memory")
130142
if err != nil {
131-
errorsArray = append(errorsArray, err)
143+
return err
132144
}
133145
}
134146

135-
return
147+
return nil
136148
}
137149

138-
func validatePerCoreMemory(vm *v1alpha2.VirtualMachine, sp *v1alpha2.SizingPolicy) (errorsArray []error) {
150+
func validatePerCoreMemory(vm *v1alpha2.VirtualMachine, sp *v1alpha2.SizingPolicy) error {
139151
if sp.Memory == nil || sp.Memory.PerCore == nil || sp.Memory.PerCore.Max == nil || sp.Memory.PerCore.Max.IsZero() {
140-
return
152+
return nil
141153
}
142154

143155
// Calculate memory portion per CPU core
@@ -147,21 +159,21 @@ func validatePerCoreMemory(vm *v1alpha2.VirtualMachine, sp *v1alpha2.SizingPolic
147159
perCoreMemory := resource.NewQuantity(vmPerCore, resource.BinarySI)
148160

149161
if sp.Memory.PerCore.Min != nil && perCoreMemory.Cmp(*sp.Memory.PerCore.Min) == common.CmpLesser {
150-
errorsArray = append(errorsArray, fmt.Errorf(
162+
return fmt.Errorf(
151163
"requested VM per core memory (%s) is less than the minimum allowed, available range [%s, %s]",
152164
perCoreMemory.String(),
153165
sp.Memory.PerCore.Min.String(),
154166
sp.Memory.PerCore.Max.String(),
155-
))
167+
)
156168
}
157169

158170
if perCoreMemory.Cmp(*sp.Memory.PerCore.Max) == common.CmpGreater {
159-
errorsArray = append(errorsArray, fmt.Errorf(
171+
return fmt.Errorf(
160172
"requested VM per core memory (%s) exceeds the maximum allowed, available range [%s, %s]",
161173
perCoreMemory.String(),
162174
sp.Memory.PerCore.Min.String(),
163175
sp.Memory.PerCore.Max.String(),
164-
))
176+
)
165177
}
166178

167179
if sp.Memory.Step != nil && !sp.Memory.Step.IsZero() {
@@ -171,11 +183,11 @@ func validatePerCoreMemory(vm *v1alpha2.VirtualMachine, sp *v1alpha2.SizingPolic
171183
}
172184
err := validateIsQuantized(*perCoreMemory, minVal, *sp.Memory.PerCore.Max, *sp.Memory.Step, "VM per core memory")
173185
if err != nil {
174-
errorsArray = append(errorsArray, err)
186+
return err
175187
}
176188
}
177189

178-
return
190+
return nil
179191
}
180192

181193
func validateIsQuantized(value, min, max, step resource.Quantity, source string) (err error) {
@@ -212,3 +224,11 @@ func generateValidGrid(min, max, step resource.Quantity) []resource.Quantity {
212224

213225
return grid
214226
}
227+
228+
func formatCoreFractionValues(cf []v1alpha2.CoreFractionValue) []string {
229+
result := make([]string, len(cf))
230+
for i, v := range cf {
231+
result[i] = fmt.Sprintf("%d%%", v)
232+
}
233+
return result
234+
}

0 commit comments

Comments
 (0)