mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
Added in-notin operator
This commit is contained in:
parent
e8c4050d49
commit
b589169b5e
6 changed files with 83 additions and 199 deletions
|
@ -233,7 +233,10 @@ spec:
|
|||
key:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: array
|
||||
items: {}
|
||||
generate:
|
||||
type: object
|
||||
required:
|
||||
|
|
|
@ -235,7 +235,10 @@ spec:
|
|||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: array
|
||||
items: {}
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
|
|
|
@ -235,7 +235,10 @@ spec:
|
|||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: array
|
||||
items: {}
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
|
|
2
go.sum
2
go.sum
|
@ -1068,6 +1068,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gotest.tools v1.4.0 h1:BjtEgfuw8Qyd+jPvQz8CfoxiO/UjFEidWinwEXZiWv0=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
|
@ -2,9 +2,7 @@ package operator
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/nirmata/kyverno/pkg/engine/context"
|
||||
|
@ -27,131 +25,76 @@ type InHandler struct {
|
|||
}
|
||||
|
||||
//Evaluate evaluates expression with In Operator
|
||||
func (eh InHandler) Evaluate(key, value interface{}) bool {
|
||||
func (in InHandler) Evaluate(key, value interface{}) bool {
|
||||
var err error
|
||||
//TODO: decouple variables from evaluation
|
||||
// substitute the variables
|
||||
if key, err = eh.subHandler(eh.log, eh.ctx, key); err != nil {
|
||||
if key, err = in.subHandler(in.log, in.ctx, key); err != nil {
|
||||
// Failed to resolve the variable
|
||||
eh.log.Error(err, "Failed to resolve variable", "variable", key)
|
||||
in.log.Error(err, "Failed to resolve variable", "variable", key)
|
||||
return false
|
||||
}
|
||||
if value, err = eh.subHandler(eh.log, eh.ctx, value); err != nil {
|
||||
if value, err = in.subHandler(in.log, in.ctx, value); err != nil {
|
||||
// Failed to resolve the variable
|
||||
eh.log.Error(err, "Failed to resolve variable", "variable", value)
|
||||
in.log.Error(err, "Failed to resolve variable", "variable", value)
|
||||
return false
|
||||
}
|
||||
|
||||
// key and value need to be of same type
|
||||
// key should be avaliable in value
|
||||
switch typedKey := key.(type) {
|
||||
case bool:
|
||||
return eh.validateValuewithBoolPattern(typedKey, value)
|
||||
case int:
|
||||
return eh.validateValuewithIntPattern(int64(typedKey), value)
|
||||
case int64:
|
||||
return eh.validateValuewithIntPattern(typedKey, value)
|
||||
case float64:
|
||||
return eh.validateValuewithFloatPattern(typedKey, value)
|
||||
case string:
|
||||
return eh.validateValuewithStringPattern(typedKey, value)
|
||||
case map[string]interface{}:
|
||||
return eh.validateValueWithMapPattern(typedKey, value)
|
||||
return in.validateValuewithStringPattern(typedKey, value)
|
||||
default:
|
||||
in.log.Info("Unsupported type", "value", typedKey, "type", fmt.Sprintf("%T", typedKey))
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (in InHandler) validateValuewithStringPattern(key string, value interface{}) (keyExists bool) {
|
||||
invalidType, keyExists := ValidateStringPattern(key, value)
|
||||
if invalidType {
|
||||
in.log.Info("expected type []string", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
return false
|
||||
}
|
||||
|
||||
return keyExists
|
||||
}
|
||||
|
||||
func ValidateStringPattern(key string, value interface{}) (invalidType bool, keyExists bool) {
|
||||
stringType := reflect.TypeOf("")
|
||||
switch valuesAvaliable := value.(type) {
|
||||
case []interface{}:
|
||||
return eh.validateValueWithSlicePattern(typedKey, value)
|
||||
for _, val := range valuesAvaliable {
|
||||
if reflect.TypeOf(val) != stringType {
|
||||
return true, false
|
||||
}
|
||||
if key == val {
|
||||
keyExists = true
|
||||
}
|
||||
}
|
||||
default:
|
||||
eh.log.Info("Unsupported type", "value", typedKey, "type", fmt.Sprintf("%T", typedKey))
|
||||
return false
|
||||
return true, false
|
||||
}
|
||||
|
||||
return invalidType, keyExists
|
||||
}
|
||||
|
||||
func (eh InHandler) validateValueWithSlicePattern(key []interface{}, value interface{}) bool {
|
||||
if val, ok := value.([]interface{}); ok {
|
||||
return reflect.DeepEqual(key, val)
|
||||
}
|
||||
eh.log.Info("Expected type []interface{}", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
func (in InHandler) validateValuewithBoolPattern(key bool, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (eh InHandler) validateValueWithMapPattern(key map[string]interface{}, value interface{}) bool {
|
||||
if val, ok := value.(map[string]interface{}); ok {
|
||||
return reflect.DeepEqual(key, val)
|
||||
}
|
||||
eh.log.Info("Expected type map[string]interface{}", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
func (in InHandler) validateValuewithIntPattern(key int64, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (eh InHandler) validateValuewithStringPattern(key string, value interface{}) bool {
|
||||
if val, ok := value.(string); ok {
|
||||
return key == val
|
||||
}
|
||||
|
||||
eh.log.Info("Expected type string", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
func (in InHandler) validateValuewithFloatPattern(key float64, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (eh InHandler) validateValuewithFloatPattern(key float64, value interface{}) bool {
|
||||
switch typedValue := value.(type) {
|
||||
case int:
|
||||
// check that float has not fraction
|
||||
if key == math.Trunc(key) {
|
||||
return int(key) == typedValue
|
||||
}
|
||||
eh.log.Info("Expected type float, found int", "typedValue", typedValue)
|
||||
case int64:
|
||||
// check that float has not fraction
|
||||
if key == math.Trunc(key) {
|
||||
return int64(key) == typedValue
|
||||
}
|
||||
eh.log.Info("Expected type float, found int", "typedValue", typedValue)
|
||||
case float64:
|
||||
return typedValue == key
|
||||
case string:
|
||||
// extract float from string
|
||||
float64Num, err := strconv.ParseFloat(typedValue, 64)
|
||||
if err != nil {
|
||||
eh.log.Error(err, "Failed to parse float64 from string")
|
||||
return false
|
||||
}
|
||||
return float64Num == key
|
||||
default:
|
||||
eh.log.Info("Expected type float", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
return false
|
||||
}
|
||||
func (in InHandler) validateValueWithMapPattern(key map[string]interface{}, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (eh InHandler) validateValuewithBoolPattern(key bool, value interface{}) bool {
|
||||
typedValue, ok := value.(bool)
|
||||
if !ok {
|
||||
eh.log.Info("Expected type bool", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
return false
|
||||
}
|
||||
return key == typedValue
|
||||
}
|
||||
|
||||
func (eh InHandler) validateValuewithIntPattern(key int64, value interface{}) bool {
|
||||
switch typedValue := value.(type) {
|
||||
case int:
|
||||
return int64(typedValue) == key
|
||||
case int64:
|
||||
return typedValue == key
|
||||
case float64:
|
||||
// check that float has no fraction
|
||||
if typedValue == math.Trunc(typedValue) {
|
||||
return int64(typedValue) == key
|
||||
}
|
||||
eh.log.Info("Expected type int, found float", "value", typedValue, "type", fmt.Sprintf("%T", typedValue))
|
||||
return false
|
||||
case string:
|
||||
// extract in64 from string
|
||||
int64Num, err := strconv.ParseInt(typedValue, 10, 64)
|
||||
if err != nil {
|
||||
eh.log.Error(err, "Failed to parse int64 from string")
|
||||
return false
|
||||
}
|
||||
return int64Num == key
|
||||
default:
|
||||
eh.log.Info("Expected type int", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
return false
|
||||
}
|
||||
func (in InHandler) validateValueWithSlicePattern(key []interface{}, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -2,9 +2,6 @@ package operator
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/nirmata/kyverno/pkg/engine/context"
|
||||
|
@ -27,129 +24,62 @@ type NotInHandler struct {
|
|||
}
|
||||
|
||||
//Evaluate evaluates expression with NotIn Operator
|
||||
func (neh NotInHandler) Evaluate(key, value interface{}) bool {
|
||||
func (nin NotInHandler) Evaluate(key, value interface{}) bool {
|
||||
var err error
|
||||
//TODO: decouple variables from evaluation
|
||||
// substitute the variables
|
||||
if key, err = neh.subHandler(neh.log, neh.ctx, key); err != nil {
|
||||
if key, err = nin.subHandler(nin.log, nin.ctx, key); err != nil {
|
||||
// Failed to resolve the variable
|
||||
neh.log.Error(err, "Failed to resolve variable", "variable", key)
|
||||
nin.log.Error(err, "Failed to resolve variable", "variable", key)
|
||||
return false
|
||||
}
|
||||
if value, err = neh.subHandler(neh.log, neh.ctx, value); err != nil {
|
||||
if value, err = nin.subHandler(nin.log, nin.ctx, value); err != nil {
|
||||
// Failed to resolve the variable
|
||||
neh.log.Error(err, "Failed to resolve variable", "variable", value)
|
||||
nin.log.Error(err, "Failed to resolve variable", "variable", value)
|
||||
return false
|
||||
}
|
||||
// key and value need to be of same type
|
||||
switch typedKey := key.(type) {
|
||||
case bool:
|
||||
return neh.validateValuewithBoolPattern(typedKey, value)
|
||||
case int:
|
||||
return neh.validateValuewithIntPattern(int64(typedKey), value)
|
||||
case int64:
|
||||
return neh.validateValuewithIntPattern(typedKey, value)
|
||||
case float64:
|
||||
return neh.validateValuewithFloatPattern(typedKey, value)
|
||||
case string:
|
||||
return neh.validateValuewithStringPattern(typedKey, value)
|
||||
case map[string]interface{}:
|
||||
return neh.validateValueWithMapPattern(typedKey, value)
|
||||
case []interface{}:
|
||||
return neh.validateValueWithSlicePattern(typedKey, value)
|
||||
return nin.validateValuewithStringPattern(typedKey, value)
|
||||
default:
|
||||
neh.log.Info("Unsupported type", "value", typedKey, "type", fmt.Sprintf("%T", typedKey))
|
||||
nin.log.Info("Unsupported type", "value", typedKey, "type", fmt.Sprintf("%T", typedKey))
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (neh NotInHandler) validateValueWithSlicePattern(key []interface{}, value interface{}) bool {
|
||||
if val, ok := value.([]interface{}); ok {
|
||||
return !reflect.DeepEqual(key, val)
|
||||
func (nin NotInHandler) validateValuewithStringPattern(key string, value interface{}) bool {
|
||||
invalidType, keyExists := ValidateStringPattern(key, value)
|
||||
if invalidType {
|
||||
nin.log.Info("expected type []string", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
return false
|
||||
}
|
||||
neh.log.Info("Expected type []interface{}", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
|
||||
if !keyExists {
|
||||
fmt.Println(".....return true......")
|
||||
return true
|
||||
}
|
||||
fmt.Println(".....return false......")
|
||||
return false
|
||||
}
|
||||
|
||||
func (neh NotInHandler) validateValueWithMapPattern(key map[string]interface{}, value interface{}) bool {
|
||||
if val, ok := value.(map[string]interface{}); ok {
|
||||
return !reflect.DeepEqual(key, val)
|
||||
}
|
||||
neh.log.Info("Expected type map[string]interface{}", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
func (nin NotInHandler) validateValuewithBoolPattern(key bool, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (neh NotInHandler) validateValuewithStringPattern(key string, value interface{}) bool {
|
||||
if val, ok := value.(string); ok {
|
||||
return key != val
|
||||
}
|
||||
neh.log.Info("Expected type string", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
func (nin NotInHandler) validateValuewithIntPattern(key int64, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (neh NotInHandler) validateValuewithFloatPattern(key float64, value interface{}) bool {
|
||||
switch typedValue := value.(type) {
|
||||
case int:
|
||||
// check that float has not fraction
|
||||
if key == math.Trunc(key) {
|
||||
return int(key) != typedValue
|
||||
}
|
||||
neh.log.Info("Expected type float, found int", "typedValue", typedValue)
|
||||
case int64:
|
||||
// check that float has not fraction
|
||||
if key == math.Trunc(key) {
|
||||
return int64(key) != typedValue
|
||||
}
|
||||
neh.log.Info("Expected type float, found int", "typedValue", typedValue)
|
||||
case float64:
|
||||
return typedValue != key
|
||||
case string:
|
||||
// extract float from string
|
||||
float64Num, err := strconv.ParseFloat(typedValue, 64)
|
||||
if err != nil {
|
||||
neh.log.Error(err, "Failed to parse float64 from string")
|
||||
return false
|
||||
}
|
||||
return float64Num != key
|
||||
default:
|
||||
neh.log.Info("Expected type float", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
return false
|
||||
}
|
||||
func (nin NotInHandler) validateValuewithFloatPattern(key float64, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (neh NotInHandler) validateValuewithBoolPattern(key bool, value interface{}) bool {
|
||||
typedValue, ok := value.(bool)
|
||||
if !ok {
|
||||
neh.log.Info("Expected type bool", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
return false
|
||||
}
|
||||
return key != typedValue
|
||||
func (nin NotInHandler) validateValueWithMapPattern(key map[string]interface{}, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (neh NotInHandler) validateValuewithIntPattern(key int64, value interface{}) bool {
|
||||
switch typedValue := value.(type) {
|
||||
case int:
|
||||
return int64(typedValue) != key
|
||||
case int64:
|
||||
return typedValue != key
|
||||
case float64:
|
||||
// check that float has no fraction
|
||||
if typedValue == math.Trunc(typedValue) {
|
||||
return int64(typedValue) != key
|
||||
}
|
||||
neh.log.Info("Expected type int, found float", "value", typedValue, "type", fmt.Sprintf("%T", typedValue))
|
||||
return false
|
||||
case string:
|
||||
// extract in64 from string
|
||||
int64Num, err := strconv.ParseInt(typedValue, 10, 64)
|
||||
if err != nil {
|
||||
neh.log.Error(err, "Failed to parse int64 from string")
|
||||
return false
|
||||
}
|
||||
return int64Num != key
|
||||
default:
|
||||
neh.log.Info("Expected type int", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
return false
|
||||
}
|
||||
func (nin NotInHandler) validateValueWithSlicePattern(key []interface{}, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue