mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
Added support for comparing resource quantities
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
This commit is contained in:
parent
64cb5d7d41
commit
509f561d67
3 changed files with 171 additions and 9 deletions
|
@ -103,6 +103,54 @@ func Test_Eval_GreaterThanOrEquals_Const_string_Fail(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_Eval_GreaterThanOrEquals_Const_quantity_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "10Gi",
|
||||
Operator: kyverno.GreaterThanOrEquals,
|
||||
Value: "1Gi",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_GreaterThanOrEquals_Const_quantity_equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1Gi",
|
||||
Operator: kyverno.GreaterThanOrEquals,
|
||||
Value: "1Gi",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_GreaterThanOrEquals_Const_quantity_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1Gi",
|
||||
Operator: kyverno.GreaterThanOrEquals,
|
||||
Value: "15Gi",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_GreaterThanOrEquals_Const_quantity_different_units(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1Gi",
|
||||
Operator: kyverno.GreaterThanOrEquals,
|
||||
Value: "10Mi",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_GreaterThan_Const_string_Equal_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
|
@ -139,6 +187,30 @@ func Test_Eval_GreaterThan_Const_string_Fail(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_Eval_GreaterThan_Const_quantity_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "10Gi",
|
||||
Operator: kyverno.GreaterThan,
|
||||
Value: "1Gi",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_GreaterThan_Const_quantity_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1Gi",
|
||||
Operator: kyverno.GreaterThan,
|
||||
Value: "1Gi",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_LessThanOrEquals_Const_string_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
|
@ -175,6 +247,54 @@ func Test_Eval_LessThanOrEquals_Const_string_Fail(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_Eval_LessThanOrEquals_Const_quantity_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1Gi",
|
||||
Operator: kyverno.LessThanOrEquals,
|
||||
Value: "10Gi",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_LessThanOrEquals_Const_quantity_equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1Gi",
|
||||
Operator: kyverno.LessThanOrEquals,
|
||||
Value: "1Gi",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_LessThanOrEquals_Const_quantity_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "15Gi",
|
||||
Operator: kyverno.LessThanOrEquals,
|
||||
Value: "1Gi",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_LessThanOrEquals_Const_quantity_different_units(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1Mi",
|
||||
Operator: kyverno.LessThanOrEquals,
|
||||
Value: "1Gi",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_LessThan_Const_string_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
|
@ -211,6 +331,30 @@ func Test_Eval_LessThan_Const_string_Fail(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_Eval_LessThan_Const_quantity_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1Gi",
|
||||
Operator: kyverno.LessThan,
|
||||
Value: "10Gi",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_LessThan_Const_quantity_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1Gi",
|
||||
Operator: kyverno.LessThan,
|
||||
Value: "1Gi",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThanOrEquals_Const_string_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/go-logr/logr"
|
||||
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
)
|
||||
|
||||
//NewNumericOperatorHandler returns handler to manage the provided numeric operations (>, >=, <=, <)
|
||||
|
@ -109,6 +110,21 @@ func (noh NumericOperatorHandler) validateValueWithFloatPattern(key float64, val
|
|||
}
|
||||
}
|
||||
|
||||
func (noh NumericOperatorHandler) validateValueWithResourcePattern(key resource.Quantity, value interface{}) bool {
|
||||
switch typedValue := value.(type) {
|
||||
case string:
|
||||
resourceValue, err := resource.ParseQuantity(typedValue)
|
||||
if err != nil {
|
||||
noh.log.Error(fmt.Errorf("parse error: "), "Failed to parse value type doesn't match key type")
|
||||
return false
|
||||
}
|
||||
return compareByCondition(float64(key.Cmp(resourceValue)), 0, noh.condition, &noh.log)
|
||||
default:
|
||||
noh.log.Info("Expected type string", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (noh NumericOperatorHandler) validateValueWithStringPattern(key string, value interface{}) bool {
|
||||
// extracting float64 from the string key
|
||||
float64key, err := strconv.ParseFloat(key, 64)
|
||||
|
@ -120,7 +136,13 @@ func (noh NumericOperatorHandler) validateValueWithStringPattern(key string, val
|
|||
if err == nil {
|
||||
return noh.validateValueWithIntPattern(int64key, value)
|
||||
}
|
||||
noh.log.Error(err, "Failed to parse both float64 and int64 from the string keyt")
|
||||
// extracting
|
||||
resourceKey, err := resource.ParseQuantity(key)
|
||||
if err == nil {
|
||||
return noh.validateValueWithResourcePattern(resourceKey, value)
|
||||
}
|
||||
|
||||
noh.log.Error(err, "Failed to parse from the string key, value is not float, int nor resource quantity")
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
@ -27,16 +27,12 @@ func CreateOperatorHandler(log logr.Logger, ctx context.EvalInterface, op kyvern
|
|||
str := strings.ToLower(string(op))
|
||||
switch str {
|
||||
|
||||
case strings.ToLower(string(kyverno.Equal)):
|
||||
case strings.ToLower(string(kyverno.Equal)),
|
||||
strings.ToLower(string(kyverno.Equals)):
|
||||
return NewEqualHandler(log, ctx)
|
||||
|
||||
case strings.ToLower(string(kyverno.Equals)):
|
||||
return NewEqualHandler(log, ctx)
|
||||
|
||||
case strings.ToLower(string(kyverno.NotEqual)):
|
||||
return NewNotEqualHandler(log, ctx)
|
||||
|
||||
case strings.ToLower(string(kyverno.NotEquals)):
|
||||
case strings.ToLower(string(kyverno.NotEqual)),
|
||||
strings.ToLower(string(kyverno.NotEquals)):
|
||||
return NewNotEqualHandler(log, ctx)
|
||||
|
||||
case strings.ToLower(string(kyverno.In)):
|
||||
|
|
Loading…
Add table
Reference in a new issue