Skip to content

Commit c9ca957

Browse files
authored
Enhance Kubernetes Resource Quantity Comparisons in Templating System (#1147) (#1156)
* support kubernetes resources quantity compaisons * add kubernetes resources quantity tests * update the document for templating system * polish the dynamic configuration with templating * removed nil error * added use cases --------- Signed-off-by: YuChen <[email protected]>
1 parent 33c91b6 commit c9ca957

File tree

3 files changed

+388
-130
lines changed

3 files changed

+388
-130
lines changed

controllers/operator/manager.go

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
authorizationv1 "k8s.io/api/authorization/v1"
3434
corev1 "k8s.io/api/core/v1"
3535
apierrors "k8s.io/apimachinery/pkg/api/errors"
36+
"k8s.io/apimachinery/pkg/api/resource"
3637
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3738
"k8s.io/apimachinery/pkg/runtime"
3839
"k8s.io/apimachinery/pkg/types"
@@ -1053,21 +1054,47 @@ func (m *ODLMOperator) EvaluateExpression(ctx context.Context, expr *util.Logica
10531054
return leftVal, rightVal, nil
10541055
}
10551056

1057+
// Helper function to compare values with support for Kubernetes resource units
1058+
compareValues := func(leftVal, rightVal string) (leftIsGreater bool, rightIsEqual bool, rightIsGreater bool) {
1059+
// Check if both are resource quantities
1060+
leftQty, leftErr := resource.ParseQuantity(strings.TrimSpace(leftVal))
1061+
rightQty, rightErr := resource.ParseQuantity(strings.TrimSpace(rightVal))
1062+
1063+
// If both are valid Kubernetes quantities, compare their values
1064+
if leftErr == nil && rightErr == nil {
1065+
cmp := leftQty.Cmp(rightQty)
1066+
return cmp > 0, cmp == 0, cmp < 0
1067+
}
1068+
1069+
// Fall back to standard float parsing
1070+
leftNum, leftFloatErr := strconv.ParseFloat(strings.TrimSpace(leftVal), 64)
1071+
rightNum, rightFloatErr := strconv.ParseFloat(strings.TrimSpace(rightVal), 64)
1072+
1073+
if leftFloatErr == nil && rightFloatErr == nil {
1074+
return leftNum > rightNum, leftNum == rightNum, leftNum < rightNum
1075+
}
1076+
1077+
// Fall back to string comparison
1078+
return leftVal > rightVal, leftVal == rightVal, leftVal < rightVal
1079+
}
1080+
10561081
// Handle basic comparison operators
10571082
if expr.Equal != nil {
10581083
leftVal, rightVal, err := getComparisonValues(expr.Equal.Left, expr.Equal.Right)
10591084
if err != nil {
10601085
return false, err
10611086
}
1062-
return leftVal == rightVal, nil
1087+
_, isEqual, _ := compareValues(leftVal, rightVal)
1088+
return isEqual, nil
10631089
}
10641090

10651091
if expr.NotEqual != nil {
10661092
leftVal, rightVal, err := getComparisonValues(expr.NotEqual.Left, expr.NotEqual.Right)
10671093
if err != nil {
10681094
return false, err
10691095
}
1070-
return leftVal != rightVal, nil
1096+
_, isEqual, _ := compareValues(leftVal, rightVal)
1097+
return !isEqual, nil
10711098
}
10721099

10731100
if expr.GreaterThan != nil {
@@ -1076,13 +1103,8 @@ func (m *ODLMOperator) EvaluateExpression(ctx context.Context, expr *util.Logica
10761103
return false, err
10771104
}
10781105

1079-
leftNum, leftErr := strconv.ParseFloat(strings.TrimSpace(leftVal), 64)
1080-
rightNum, rightErr := strconv.ParseFloat(strings.TrimSpace(rightVal), 64)
1081-
1082-
if leftErr == nil && rightErr == nil {
1083-
return leftNum > rightNum, nil
1084-
}
1085-
return leftVal > rightVal, nil
1106+
leftGreater, _, _ := compareValues(leftVal, rightVal)
1107+
return leftGreater, nil
10861108
}
10871109

10881110
if expr.LessThan != nil {
@@ -1091,13 +1113,8 @@ func (m *ODLMOperator) EvaluateExpression(ctx context.Context, expr *util.Logica
10911113
return false, err
10921114
}
10931115

1094-
leftNum, leftErr := strconv.ParseFloat(strings.TrimSpace(leftVal), 64)
1095-
rightNum, rightErr := strconv.ParseFloat(strings.TrimSpace(rightVal), 64)
1096-
1097-
if leftErr == nil && rightErr == nil {
1098-
return leftNum < rightNum, nil
1099-
}
1100-
return leftVal < rightVal, nil
1116+
_, _, leftLess := compareValues(leftVal, rightVal)
1117+
return leftLess, nil
11011118
}
11021119

11031120
// Handle logical operators

controllers/operator/manager_test.go

Lines changed: 124 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ func TestEvaluateExpression(t *testing.T) {
561561
expectError: false,
562562
},
563563
{
564-
name: "GreaterThan comparison with strings",
564+
name: "GreaterThan comparison with strings - true",
565565
expr: &util.LogicalExpression{
566566
GreaterThan: &util.ValueComparison{
567567
Left: &util.ValueSource{Literal: "xyz"},
@@ -594,7 +594,7 @@ func TestEvaluateExpression(t *testing.T) {
594594
expectError: false,
595595
},
596596
{
597-
name: "LessThan comparison with strings",
597+
name: "LessThan comparison with strings - true",
598598
expr: &util.LogicalExpression{
599599
LessThan: &util.ValueComparison{
600600
Left: &util.ValueSource{Literal: "abc"},
@@ -604,6 +604,128 @@ func TestEvaluateExpression(t *testing.T) {
604604
expectedResult: true,
605605
expectError: false,
606606
},
607+
// Kubernetes resource quantity tests
608+
{
609+
name: "GreaterThan comparison with memory quantities - true",
610+
expr: &util.LogicalExpression{
611+
GreaterThan: &util.ValueComparison{
612+
Left: &util.ValueSource{Literal: "10Gi"},
613+
Right: &util.ValueSource{Literal: "2Gi"},
614+
},
615+
},
616+
expectedResult: true,
617+
expectError: false,
618+
},
619+
{
620+
name: "GreaterThan comparison with memory quantities - false",
621+
expr: &util.LogicalExpression{
622+
GreaterThan: &util.ValueComparison{
623+
Left: &util.ValueSource{Literal: "100Mi"},
624+
Right: &util.ValueSource{Literal: "1Gi"},
625+
},
626+
},
627+
expectedResult: false,
628+
expectError: false,
629+
},
630+
{
631+
name: "LessThan comparison with memory quantities - true",
632+
expr: &util.LogicalExpression{
633+
LessThan: &util.ValueComparison{
634+
Left: &util.ValueSource{Literal: "500Mi"},
635+
Right: &util.ValueSource{Literal: "1Gi"},
636+
},
637+
},
638+
expectedResult: true,
639+
expectError: false,
640+
},
641+
{
642+
name: "LessThan comparison with memory quantities - false",
643+
expr: &util.LogicalExpression{
644+
LessThan: &util.ValueComparison{
645+
Left: &util.ValueSource{Literal: "5Gi"},
646+
Right: &util.ValueSource{Literal: "2Gi"},
647+
},
648+
},
649+
expectedResult: false,
650+
expectError: false,
651+
},
652+
{
653+
name: "Equal comparison with CPU quantities",
654+
expr: &util.LogicalExpression{
655+
Equal: &util.ValueComparison{
656+
Left: &util.ValueSource{Literal: "1000m"},
657+
Right: &util.ValueSource{Literal: "1"},
658+
},
659+
},
660+
expectedResult: true,
661+
expectError: false,
662+
},
663+
{
664+
name: "Equal comparison with different unit formats",
665+
expr: &util.LogicalExpression{
666+
Equal: &util.ValueComparison{
667+
Left: &util.ValueSource{Literal: "1Gi"},
668+
Right: &util.ValueSource{Literal: "1024Mi"},
669+
},
670+
},
671+
expectedResult: true,
672+
expectError: false,
673+
},
674+
{
675+
name: "GreaterThan comparison with CPU quantities",
676+
expr: &util.LogicalExpression{
677+
GreaterThan: &util.ValueComparison{
678+
Left: &util.ValueSource{Literal: "2"},
679+
Right: &util.ValueSource{Literal: "1500m"},
680+
},
681+
},
682+
expectedResult: true,
683+
expectError: false,
684+
},
685+
{
686+
name: "GreaterThan comparison with mixed format units",
687+
expr: &util.LogicalExpression{
688+
GreaterThan: &util.ValueComparison{
689+
Left: &util.ValueSource{Literal: "1Mi"},
690+
Right: &util.ValueSource{Literal: "1024Ki"},
691+
},
692+
},
693+
expectedResult: false,
694+
expectError: false,
695+
},
696+
{
697+
name: "Mixed resource types - comparing memory and CPU",
698+
expr: &util.LogicalExpression{
699+
Equal: &util.ValueComparison{
700+
Left: &util.ValueSource{Literal: "100m"},
701+
Right: &util.ValueSource{Literal: "100Mi"},
702+
},
703+
},
704+
expectedResult: false,
705+
expectError: false,
706+
},
707+
{
708+
name: "NotEqual comparison with memory quantities - true",
709+
expr: &util.LogicalExpression{
710+
NotEqual: &util.ValueComparison{
711+
Left: &util.ValueSource{Literal: "2Gi"},
712+
Right: &util.ValueSource{Literal: "1Gi"},
713+
},
714+
},
715+
expectedResult: true,
716+
expectError: false,
717+
},
718+
{
719+
name: "NotEqual comparison with memory quantities - false",
720+
expr: &util.LogicalExpression{
721+
NotEqual: &util.ValueComparison{
722+
Left: &util.ValueSource{Literal: "1Gi"},
723+
Right: &util.ValueSource{Literal: "1024Mi"},
724+
},
725+
},
726+
expectedResult: false,
727+
expectError: false,
728+
},
607729
{
608730
name: "And operator - all true",
609731
expr: &util.LogicalExpression{

0 commit comments

Comments
 (0)