mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
Fix parsing of resources in preconditions (#3108)
Signed-off-by: Sambhav Kothari <sambhavs.email@gmail.com>
This commit is contained in:
parent
851ebe3e65
commit
a1daf167e7
2 changed files with 47 additions and 20 deletions
|
@ -23,6 +23,8 @@ func TestEvaluate(t *testing.T) {
|
|||
{kyverno.Condition{Key: 1.0, Operator: kyverno.ConditionOperators["Equals"], Value: 1.0}, true},
|
||||
{kyverno.Condition{Key: true, Operator: kyverno.ConditionOperators["Equals"], Value: true}, true},
|
||||
{kyverno.Condition{Key: false, Operator: kyverno.ConditionOperators["Equals"], Value: false}, true},
|
||||
{kyverno.Condition{Key: "1024", Operator: kyverno.ConditionOperators["Equals"], Value: "1Ki"}, true},
|
||||
{kyverno.Condition{Key: "1Ki", Operator: kyverno.ConditionOperators["Equals"], Value: "1024"}, true},
|
||||
{kyverno.Condition{Key: "1Gi", Operator: kyverno.ConditionOperators["Equals"], Value: "1Gi"}, true},
|
||||
{kyverno.Condition{Key: "1Gi", Operator: kyverno.ConditionOperators["Equals"], Value: "1024Mi"}, true},
|
||||
{kyverno.Condition{Key: "1h", Operator: kyverno.ConditionOperators["Equals"], Value: "1h"}, true},
|
||||
|
@ -63,6 +65,10 @@ func TestEvaluate(t *testing.T) {
|
|||
{kyverno.Condition{Key: 1.0, Operator: kyverno.ConditionOperators["NotEquals"], Value: 1.0}, false},
|
||||
{kyverno.Condition{Key: true, Operator: kyverno.ConditionOperators["NotEquals"], Value: false}, true},
|
||||
{kyverno.Condition{Key: false, Operator: kyverno.ConditionOperators["NotEquals"], Value: false}, false},
|
||||
{kyverno.Condition{Key: "1024", Operator: kyverno.ConditionOperators["NotEquals"], Value: "1Ki"}, false},
|
||||
{kyverno.Condition{Key: "1Ki", Operator: kyverno.ConditionOperators["NotEquals"], Value: "1024"}, false},
|
||||
{kyverno.Condition{Key: "1023", Operator: kyverno.ConditionOperators["NotEquals"], Value: "1Ki"}, true},
|
||||
{kyverno.Condition{Key: "1Ki", Operator: kyverno.ConditionOperators["NotEquals"], Value: "1023"}, true},
|
||||
{kyverno.Condition{Key: "1Gi", Operator: kyverno.ConditionOperators["NotEquals"], Value: "1Gi"}, false},
|
||||
{kyverno.Condition{Key: "10Gi", Operator: kyverno.ConditionOperators["NotEquals"], Value: "1024Mi"}, true},
|
||||
{kyverno.Condition{Key: "1h", Operator: kyverno.ConditionOperators["NotEquals"], Value: "1h"}, false},
|
||||
|
@ -104,6 +110,8 @@ func TestEvaluate(t *testing.T) {
|
|||
{kyverno.Condition{Key: 1, Operator: kyverno.ConditionOperators["GreaterThan"], Value: 1.5}, false},
|
||||
{kyverno.Condition{Key: 1, Operator: kyverno.ConditionOperators["GreaterThan"], Value: 1}, false},
|
||||
{kyverno.Condition{Key: 1.0, Operator: kyverno.ConditionOperators["GreaterThan"], Value: 1.0}, false},
|
||||
{kyverno.Condition{Key: "1025", Operator: kyverno.ConditionOperators["GreaterThan"], Value: "1Ki"}, true},
|
||||
{kyverno.Condition{Key: "1Ki", Operator: kyverno.ConditionOperators["GreaterThan"], Value: "1023"}, true},
|
||||
{kyverno.Condition{Key: "10Gi", Operator: kyverno.ConditionOperators["GreaterThan"], Value: "1Gi"}, true},
|
||||
{kyverno.Condition{Key: "1Gi", Operator: kyverno.ConditionOperators["GreaterThan"], Value: "1Mi"}, true},
|
||||
{kyverno.Condition{Key: "1Gi", Operator: kyverno.ConditionOperators["GreaterThan"], Value: "10Gi"}, false},
|
||||
|
@ -147,6 +155,8 @@ func TestEvaluate(t *testing.T) {
|
|||
{kyverno.Condition{Key: 1, Operator: kyverno.ConditionOperators["LessThan"], Value: 1.5}, true},
|
||||
{kyverno.Condition{Key: 1, Operator: kyverno.ConditionOperators["LessThan"], Value: 1}, false},
|
||||
{kyverno.Condition{Key: 1.0, Operator: kyverno.ConditionOperators["LessThan"], Value: 1.0}, false},
|
||||
{kyverno.Condition{Key: "1023", Operator: kyverno.ConditionOperators["LessThan"], Value: "1Ki"}, true},
|
||||
{kyverno.Condition{Key: "1Ki", Operator: kyverno.ConditionOperators["LessThan"], Value: "1025"}, true},
|
||||
{kyverno.Condition{Key: "10Gi", Operator: kyverno.ConditionOperators["LessThan"], Value: "1Gi"}, false},
|
||||
{kyverno.Condition{Key: "1Gi", Operator: kyverno.ConditionOperators["LessThan"], Value: "10Gi"}, true},
|
||||
{kyverno.Condition{Key: "1Gi", Operator: kyverno.ConditionOperators["LessThan"], Value: "1Mi"}, false},
|
||||
|
@ -191,6 +201,10 @@ func TestEvaluate(t *testing.T) {
|
|||
{kyverno.Condition{Key: 1, Operator: kyverno.ConditionOperators["GreaterThanOrEquals"], Value: 1}, true},
|
||||
{kyverno.Condition{Key: 1.0, Operator: kyverno.ConditionOperators["GreaterThanOrEquals"], Value: 1.0}, true},
|
||||
{kyverno.Condition{Key: 1.0, Operator: kyverno.ConditionOperators["GreaterThanOrEquals"], Value: 1}, true},
|
||||
{kyverno.Condition{Key: "1025", Operator: kyverno.ConditionOperators["GreaterThanOrEquals"], Value: "1Ki"}, true},
|
||||
{kyverno.Condition{Key: "1024", Operator: kyverno.ConditionOperators["GreaterThanOrEquals"], Value: "1Ki"}, true},
|
||||
{kyverno.Condition{Key: "1Ki", Operator: kyverno.ConditionOperators["GreaterThanOrEquals"], Value: "1023"}, true},
|
||||
{kyverno.Condition{Key: "1Ki", Operator: kyverno.ConditionOperators["GreaterThanOrEquals"], Value: "1024"}, true},
|
||||
{kyverno.Condition{Key: "10Gi", Operator: kyverno.ConditionOperators["GreaterThanOrEquals"], Value: "1Gi"}, true},
|
||||
{kyverno.Condition{Key: "1Gi", Operator: kyverno.ConditionOperators["GreaterThanOrEquals"], Value: "1Mi"}, true},
|
||||
{kyverno.Condition{Key: "1Gi", Operator: kyverno.ConditionOperators["GreaterThanOrEquals"], Value: "10Gi"}, false},
|
||||
|
@ -229,6 +243,10 @@ func TestEvaluate(t *testing.T) {
|
|||
{kyverno.Condition{Key: 1, Operator: kyverno.ConditionOperators["LessThanOrEquals"], Value: 1.5}, true},
|
||||
{kyverno.Condition{Key: 1, Operator: kyverno.ConditionOperators["LessThanOrEquals"], Value: 1}, true},
|
||||
{kyverno.Condition{Key: 1.0, Operator: kyverno.ConditionOperators["LessThanOrEquals"], Value: 1.0}, true},
|
||||
{kyverno.Condition{Key: "1Ki", Operator: kyverno.ConditionOperators["LessThanOrEquals"], Value: "1024"}, true},
|
||||
{kyverno.Condition{Key: "1024", Operator: kyverno.ConditionOperators["LessThanOrEquals"], Value: "1Ki"}, true},
|
||||
{kyverno.Condition{Key: "1Ki", Operator: kyverno.ConditionOperators["LessThanOrEquals"], Value: "1025"}, true},
|
||||
{kyverno.Condition{Key: "1023", Operator: kyverno.ConditionOperators["LessThanOrEquals"], Value: "1Ki"}, true},
|
||||
{kyverno.Condition{Key: "10Gi", Operator: kyverno.ConditionOperators["LessThanOrEquals"], Value: "1Gi"}, false},
|
||||
{kyverno.Condition{Key: "1Gi", Operator: kyverno.ConditionOperators["LessThanOrEquals"], Value: "10Gi"}, true},
|
||||
{kyverno.Condition{Key: "1Gi", Operator: kyverno.ConditionOperators["LessThanOrEquals"], Value: "1Mi"}, false},
|
||||
|
|
|
@ -135,21 +135,6 @@ 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) validateValueWithVersionPattern(key semver.Version, value interface{}) bool {
|
||||
switch typedValue := value.(type) {
|
||||
case string:
|
||||
|
@ -171,6 +156,11 @@ func (noh NumericOperatorHandler) validateValueWithStringPattern(key string, val
|
|||
if err == nil {
|
||||
return compareByCondition(float64(durationKey.Seconds()), float64(durationValue.Seconds()), noh.condition, &noh.log)
|
||||
}
|
||||
// attempt to extract resource quantity from string before parsing floats/ints as resources can also be ints/floats represented as string type
|
||||
resourceKey, resourceValue, err := parseQuantity(key, value)
|
||||
if err == nil {
|
||||
return compareByCondition(float64(resourceKey.Cmp(resourceValue)), 0, noh.condition, &noh.log)
|
||||
}
|
||||
// extracting float64 from the string key
|
||||
float64key, err := strconv.ParseFloat(key, 64)
|
||||
if err == nil {
|
||||
|
@ -181,11 +171,6 @@ func (noh NumericOperatorHandler) validateValueWithStringPattern(key string, val
|
|||
if err == nil {
|
||||
return noh.validateValueWithIntPattern(int64key, value)
|
||||
}
|
||||
// attempt to extract resource quantity from string
|
||||
resourceKey, err := resource.ParseQuantity(key)
|
||||
if err == nil {
|
||||
return noh.validateValueWithResourcePattern(resourceKey, value)
|
||||
}
|
||||
// attempt to extract version from string
|
||||
versionKey, err := semver.Parse(key)
|
||||
if err == nil {
|
||||
|
@ -196,6 +181,30 @@ func (noh NumericOperatorHandler) validateValueWithStringPattern(key string, val
|
|||
return false
|
||||
}
|
||||
|
||||
func parseQuantity(key, value interface{}) (parsedKey, parsedValue resource.Quantity, err error) {
|
||||
switch typedKey := key.(type) {
|
||||
case string:
|
||||
parsedKey, err = resource.ParseQuantity(typedKey)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("key is not a quantity")
|
||||
return
|
||||
}
|
||||
switch typedValue := value.(type) {
|
||||
case string:
|
||||
parsedValue, err = resource.ParseQuantity(typedValue)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("value is not a quantity")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// the following functions are unreachable because the key is strictly supposed to be numeric
|
||||
// still the following functions are just created to make NumericOperatorHandler struct implement OperatorHandler interface
|
||||
func (noh NumericOperatorHandler) validateValueWithBoolPattern(key bool, value interface{}) bool {
|
||||
|
|
Loading…
Add table
Reference in a new issue