1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-15 17:51:20 +00:00

*Range Operators (#2622)

* Range operator: first iteration

Signed-off-by: Łukasz Jakimczuk <lukasz.j@giantswarm.io>

* Changing hyphen to colon

Signed-off-by: Łukasz Jakimczuk <lukasz.j@giantswarm.io>

* Accounting for negative numbers

Signed-off-by: Łukasz Jakimczuk <lukasz.j@giantswarm.io>

* View on the second version

Signed-off-by: Łukasz Jakimczuk <lukasz.j@giantswarm.io>

* Adding tests to the operator

Signed-off-by: Łukasz Jakimczuk <lukasz.j@giantswarm.io>

* Renoving negative support

Signed-off-by: Łukasz Jakimczuk <lukasz.j@giantswarm.io>

* Adding comment

Signed-off-by: Łukasz Jakimczuk <lukasz.j@giantswarm.io>

* Signing

Signed-off-by: Łukasz Jakimczuk <lukasz.j@giantswarm.io>

* Going for the regexp version of operator

Signed-off-by: Łukasz Jakimczuk <lukasz.j@giantswarm.io>

* Adding negative range operator

Signed-off-by: Łukasz Jakimczuk <lukasz.j@giantswarm.io>
This commit is contained in:
Lukasz Jakimczuk 2021-10-29 13:48:23 +02:00 committed by GitHub
parent a923dce631
commit ca975b8e99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 94 additions and 4 deletions

View file

@ -1,5 +1,9 @@
package operator
import (
"regexp"
)
// Operator is string alias that represents selection operators enum
type Operator string
@ -16,6 +20,10 @@ const (
More Operator = ">"
// Less stands for <
Less Operator = "<"
// InRange stands for -
InRange Operator = "-"
// NotInRange stands for !-
NotInRange Operator = "!-"
)
//ReferenceSign defines the operator for anchor reference
@ -47,5 +55,13 @@ func GetOperatorFromStringPattern(pattern string) Operator {
return NotEqual
}
if match, _ := regexp.Match(`^(\d+(\.\d+)?)([^-]*)!-(\d+(\.\d+)?)([^-]*)$`, []byte(pattern)); match {
return NotInRange
}
if match, _ := regexp.Match(`^(\d+(\.\d+)?)([^-]*)-(\d+(\.\d+)?)([^-]*)$`, []byte(pattern)); match {
return InRange
}
return Equal
}

View file

@ -17,3 +17,19 @@ func TestGetOperatorFromStringPattern_EmptyString(t *testing.T) {
func TestGetOperatorFromStringPattern_OnlyOperator(t *testing.T) {
assert.Equal(t, GetOperatorFromStringPattern(">="), MoreEqual)
}
func TestGetOperatorFromStringPattern_RangeOperator(t *testing.T) {
assert.Equal(t, GetOperatorFromStringPattern("0-1"), InRange)
assert.Equal(t, GetOperatorFromStringPattern("0Mi-1024Mi"), InRange)
assert.Equal(t, GetOperatorFromStringPattern("0!-1"), NotInRange)
assert.Equal(t, GetOperatorFromStringPattern("0Mi!-1024Mi"), NotInRange)
assert.Equal(t, GetOperatorFromStringPattern("text1024Mi-2048Mi"), Equal)
assert.Equal(t, GetOperatorFromStringPattern("test-value"), Equal)
assert.Equal(t, GetOperatorFromStringPattern("value-*"), Equal)
assert.Equal(t, GetOperatorFromStringPattern("text1024Mi!-2048Mi"), Equal)
assert.Equal(t, GetOperatorFromStringPattern("test!-value"), Equal)
assert.Equal(t, GetOperatorFromStringPattern("value!-*"), Equal)
}

View file

@ -177,17 +177,39 @@ func checkForAndConditionsAndValidate(log logr.Logger, value interface{}, patter
// Handler for single pattern value during validation process
// Detects if pattern has a number
func validateValueWithStringPattern(log logr.Logger, value interface{}, pattern string) bool {
operatorVariable := operator.GetOperatorFromStringPattern(pattern)
operator := operator.GetOperatorFromStringPattern(pattern)
pattern = pattern[len(operator):]
// Upon encountering InRange operator split the string by `-` and basically
// verify the result of (x >= leftEndpoint & x <= rightEndpoint)
if operatorVariable == operator.InRange {
gt := validateValueWithStringPattern(log, value, fmt.Sprintf(">=%s", strings.Split(pattern, "-")[0]))
if !gt {
return false
}
pattern = fmt.Sprintf("<=%s", strings.Split(pattern, "-")[1])
operatorVariable = operator.LessEqual
}
// Upon encountering NotInRange operator split the string by `!-` and basically
// verify the result of (x < leftEndpoint | x > rightEndpoint)
if operatorVariable == operator.NotInRange {
gt := validateValueWithStringPattern(log, value, fmt.Sprintf("<%s", strings.Split(pattern, "!-")[0]))
if gt {
return true
}
pattern = fmt.Sprintf(">%s", strings.Split(pattern, "!-")[1])
operatorVariable = operator.More
}
pattern = pattern[len(operatorVariable):]
pattern = strings.TrimSpace(pattern)
number, str := getNumberAndStringPartsFromPattern(pattern)
if number == "" {
return validateString(log, value, str, operator)
return validateString(log, value, str, operatorVariable)
}
return validateNumberWithStr(log, value, pattern, operator)
return validateNumberWithStr(log, value, pattern, operatorVariable)
}
// Handler for string values

View file

@ -310,6 +310,42 @@ func TestValidateValueWithStringPattern_WithSpace(t *testing.T) {
assert.Assert(t, validateValueWithStringPattern(log.Log, 4, ">= 3"))
}
func TestValidateValueWithStringPattern_Ranges(t *testing.T) {
assert.Assert(t, validateValueWithStringPattern(log.Log, 0, "0-2"))
assert.Assert(t, validateValueWithStringPattern(log.Log, 1, "0-2"))
assert.Assert(t, validateValueWithStringPattern(log.Log, 2, "0-2"))
assert.Assert(t, !validateValueWithStringPattern(log.Log, 3, "0-2"))
assert.Assert(t, validateValueWithStringPattern(log.Log, 0, "10!-20"))
assert.Assert(t, !validateValueWithStringPattern(log.Log, 15, "10!-20"))
assert.Assert(t, validateValueWithStringPattern(log.Log, 25, "10!-20"))
assert.Assert(t, !validateValueWithStringPattern(log.Log, 0, "0.00001-2.00001"))
assert.Assert(t, validateValueWithStringPattern(log.Log, 1, "0.00001-2.00001"))
assert.Assert(t, validateValueWithStringPattern(log.Log, 2, "0.00001-2.00001"))
assert.Assert(t, !validateValueWithStringPattern(log.Log, 2.0001, "0.00001-2.00001"))
assert.Assert(t, validateValueWithStringPattern(log.Log, 0, "0.00001!-2.00001"))
assert.Assert(t, !validateValueWithStringPattern(log.Log, 1, "0.00001!-2.00001"))
assert.Assert(t, !validateValueWithStringPattern(log.Log, 2, "0.00001!-2.00001"))
assert.Assert(t, validateValueWithStringPattern(log.Log, 2.0001, "0.00001!-2.00001"))
assert.Assert(t, validateValueWithStringPattern(log.Log, 2, "2-2"))
assert.Assert(t, !validateValueWithStringPattern(log.Log, 2, "2!-2"))
assert.Assert(t, validateValueWithStringPattern(log.Log, 2.99999, "2.99998-3"))
assert.Assert(t, validateValueWithStringPattern(log.Log, 2.99997, "2.99998!-3"))
assert.Assert(t, validateValueWithStringPattern(log.Log, 3.00001, "2.99998!-3"))
assert.Assert(t, validateValueWithStringPattern(log.Log, "256Mi", "128Mi-512Mi"))
assert.Assert(t, !validateValueWithStringPattern(log.Log, "1024Mi", "128Mi-512Mi"))
assert.Assert(t, !validateValueWithStringPattern(log.Log, "64Mi", "128Mi-512Mi"))
assert.Assert(t, !validateValueWithStringPattern(log.Log, "256Mi", "128Mi!-512Mi"))
assert.Assert(t, validateValueWithStringPattern(log.Log, "1024Mi", "128Mi!-512Mi"))
assert.Assert(t, validateValueWithStringPattern(log.Log, "64Mi", "128Mi!-512Mi"))
}
func TestValidateNumberWithStr_LessFloatAndInt(t *testing.T) {
assert.Assert(t, validateNumberWithStr(log.Log, 7.00001, "7.000001", operator.More))
assert.Assert(t, validateNumberWithStr(log.Log, 7.00001, "7", operator.NotEqual))