1
0
Fork 0
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:
Sambhav Kothari 2022-01-31 16:18:31 +00:00 committed by GitHub
parent 851ebe3e65
commit a1daf167e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 20 deletions

View file

@ -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},

View file

@ -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 {