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

Added in-notin operator

This commit is contained in:
NoSkillGirl 2020-06-24 12:27:08 +05:30
parent e8c4050d49
commit b589169b5e
6 changed files with 83 additions and 199 deletions

View file

@ -233,7 +233,10 @@ spec:
key: key:
type: string type: string
value: value:
type: string anyOf:
- type: string
- type: array
items: {}
generate: generate:
type: object type: object
required: required:

View file

@ -235,7 +235,10 @@ spec:
- NotIn - NotIn
type: string type: string
value: value:
type: string anyOf:
- type: string
- type: array
items: {}
required: required:
- key - key
- operator - operator

View file

@ -235,7 +235,10 @@ spec:
- NotIn - NotIn
type: string type: string
value: value:
type: string anyOf:
- type: string
- type: array
items: {}
required: required:
- key - key
- operator - operator

2
go.sum
View file

@ -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.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 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= 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-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View file

@ -2,9 +2,7 @@ package operator
import ( import (
"fmt" "fmt"
"math"
"reflect" "reflect"
"strconv"
"github.com/go-logr/logr" "github.com/go-logr/logr"
"github.com/nirmata/kyverno/pkg/engine/context" "github.com/nirmata/kyverno/pkg/engine/context"
@ -27,131 +25,76 @@ type InHandler struct {
} }
//Evaluate evaluates expression with In Operator //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 var err error
//TODO: decouple variables from evaluation //TODO: decouple variables from evaluation
// substitute the variables // 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 // 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 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 // 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 return false
} }
// key and value need to be of same type // key should be avaliable in value
switch typedKey := key.(type) { 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: case string:
return eh.validateValuewithStringPattern(typedKey, value) return in.validateValuewithStringPattern(typedKey, value)
case map[string]interface{}: default:
return eh.validateValueWithMapPattern(typedKey, value) 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{}: 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: default:
eh.log.Info("Unsupported type", "value", typedKey, "type", fmt.Sprintf("%T", typedKey)) return true, false
return false
} }
return invalidType, keyExists
} }
func (eh InHandler) validateValueWithSlicePattern(key []interface{}, value interface{}) bool { func (in InHandler) validateValuewithBoolPattern(key bool, 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))
return false return false
} }
func (eh InHandler) validateValueWithMapPattern(key map[string]interface{}, value interface{}) bool { func (in InHandler) validateValuewithIntPattern(key int64, 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))
return false return false
} }
func (eh InHandler) validateValuewithStringPattern(key string, value interface{}) bool { func (in InHandler) validateValuewithFloatPattern(key float64, 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))
return false return false
} }
func (eh InHandler) validateValuewithFloatPattern(key float64, value interface{}) bool { func (in InHandler) validateValueWithMapPattern(key map[string]interface{}, 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
}
return false return false
} }
func (eh InHandler) validateValuewithBoolPattern(key bool, value interface{}) bool { func (in InHandler) validateValueWithSlicePattern(key []interface{}, value interface{}) bool {
typedValue, ok := value.(bool) return false
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
}
} }

View file

@ -2,9 +2,6 @@ package operator
import ( import (
"fmt" "fmt"
"math"
"reflect"
"strconv"
"github.com/go-logr/logr" "github.com/go-logr/logr"
"github.com/nirmata/kyverno/pkg/engine/context" "github.com/nirmata/kyverno/pkg/engine/context"
@ -27,129 +24,62 @@ type NotInHandler struct {
} }
//Evaluate evaluates expression with NotIn Operator //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 var err error
//TODO: decouple variables from evaluation //TODO: decouple variables from evaluation
// substitute the variables // 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 // 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 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 // 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 return false
} }
// key and value need to be of same type // key and value need to be of same type
switch typedKey := key.(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: case string:
return neh.validateValuewithStringPattern(typedKey, value) return nin.validateValuewithStringPattern(typedKey, value)
case map[string]interface{}:
return neh.validateValueWithMapPattern(typedKey, value)
case []interface{}:
return neh.validateValueWithSlicePattern(typedKey, value)
default: 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 return false
} }
} }
func (neh NotInHandler) validateValueWithSlicePattern(key []interface{}, value interface{}) bool { func (nin NotInHandler) validateValuewithStringPattern(key string, value interface{}) bool {
if val, ok := value.([]interface{}); ok { invalidType, keyExists := ValidateStringPattern(key, value)
return !reflect.DeepEqual(key, val) 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 return false
} }
func (neh NotInHandler) validateValueWithMapPattern(key map[string]interface{}, value interface{}) bool { func (nin NotInHandler) validateValuewithBoolPattern(key bool, 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))
return false return false
} }
func (neh NotInHandler) validateValuewithStringPattern(key string, value interface{}) bool { func (nin NotInHandler) validateValuewithIntPattern(key int64, 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))
return false return false
} }
func (neh NotInHandler) validateValuewithFloatPattern(key float64, value interface{}) bool { func (nin 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
}
return false return false
} }
func (neh NotInHandler) validateValuewithBoolPattern(key bool, value interface{}) bool { func (nin NotInHandler) validateValueWithMapPattern(key map[string]interface{}, value interface{}) bool {
typedValue, ok := value.(bool) return false
if !ok {
neh.log.Info("Expected type bool", "value", value, "type", fmt.Sprintf("%T", value))
return false
}
return key != typedValue
} }
func (neh NotInHandler) validateValuewithIntPattern(key int64, value interface{}) bool { func (nin NotInHandler) validateValueWithSlicePattern(key []interface{}, value interface{}) bool {
switch typedValue := value.(type) { return false
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
}
} }