mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
Merge pull request #947 from NoSkillGirl/feature/new_operators
Feature/new operators
This commit is contained in:
commit
ec7969df31
9 changed files with 219 additions and 3 deletions
|
@ -226,6 +226,8 @@ spec:
|
|||
- Equals
|
||||
- NotEqual
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
|
|
|
@ -228,10 +228,15 @@ spec:
|
|||
- Equals
|
||||
- NotEqual
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
key:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: array
|
||||
items: {}
|
||||
generate:
|
||||
type: object
|
||||
required:
|
||||
|
|
|
@ -231,9 +231,14 @@ spec:
|
|||
- Equals
|
||||
- NotEqual
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: array
|
||||
items: {}
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
|
|
|
@ -231,9 +231,14 @@ spec:
|
|||
- Equals
|
||||
- NotEqual
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: array
|
||||
items: {}
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
|
|
|
@ -9,6 +9,8 @@ While `match` & `exclude` conditions allow filtering requests based on resource
|
|||
The following operators are currently supported for preconditon evaluation:
|
||||
- Equal
|
||||
- NotEqual
|
||||
- In
|
||||
- NotIn
|
||||
|
||||
## Example
|
||||
|
||||
|
@ -26,5 +28,19 @@ The following operators are currently supported for preconditon evaluation:
|
|||
|
||||
In the above example, the rule is only applied to requests from service accounts i.e. when the `{{serviceAccountName}}` is not empty.
|
||||
|
||||
```yaml
|
||||
- name: generate-default-build-role
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Namespace
|
||||
preconditions:
|
||||
- key: "{{serviceAccountName}}"
|
||||
operator: In
|
||||
value: ["build-default", "build-base"]
|
||||
```
|
||||
|
||||
In the above example, the rule is only applied to requests from service account with name `build-default` and `build-base`.
|
||||
|
||||
|
||||
<small>*Read Next >> [Auto-Generation for Pod Controllers](/documentation/writing-policies-autogen.md)*</small>
|
||||
|
|
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=
|
||||
|
|
96
pkg/engine/variables/operator/in.go
Normal file
96
pkg/engine/variables/operator/in.go
Normal file
|
@ -0,0 +1,96 @@
|
|||
package operator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/nirmata/kyverno/pkg/engine/context"
|
||||
)
|
||||
|
||||
//NewInHandler returns handler to manage In operations
|
||||
func NewInHandler(log logr.Logger, ctx context.EvalInterface, subHandler VariableSubstitutionHandler) OperatorHandler {
|
||||
return InHandler{
|
||||
ctx: ctx,
|
||||
subHandler: subHandler,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
//InHandler provides implementation to handle In Operator
|
||||
type InHandler struct {
|
||||
ctx context.EvalInterface
|
||||
subHandler VariableSubstitutionHandler
|
||||
log logr.Logger
|
||||
}
|
||||
|
||||
//Evaluate evaluates expression with In Operator
|
||||
func (in InHandler) Evaluate(key, value interface{}) bool {
|
||||
var err error
|
||||
// substitute the variables
|
||||
if key, err = in.subHandler(in.log, in.ctx, key); err != nil {
|
||||
in.log.Error(err, "Failed to resolve variable", "variable", key)
|
||||
return false
|
||||
}
|
||||
if value, err = in.subHandler(in.log, in.ctx, value); err != nil {
|
||||
in.log.Error(err, "Failed to resolve variable", "variable", value)
|
||||
return false
|
||||
}
|
||||
|
||||
switch typedKey := key.(type) {
|
||||
case string:
|
||||
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{}:
|
||||
for _, val := range valuesAvaliable {
|
||||
if reflect.TypeOf(val) != stringType {
|
||||
return true, false
|
||||
}
|
||||
if key == val {
|
||||
keyExists = true
|
||||
}
|
||||
}
|
||||
default:
|
||||
return true, false
|
||||
}
|
||||
|
||||
return invalidType, keyExists
|
||||
}
|
||||
|
||||
func (in InHandler) validateValuewithBoolPattern(key bool, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (in InHandler) validateValuewithIntPattern(key int64, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (in InHandler) validateValuewithFloatPattern(key float64, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (in InHandler) validateValueWithMapPattern(key map[string]interface{}, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (in InHandler) validateValueWithSlicePattern(key []interface{}, value interface{}) bool {
|
||||
return false
|
||||
}
|
81
pkg/engine/variables/operator/notin.go
Normal file
81
pkg/engine/variables/operator/notin.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package operator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/nirmata/kyverno/pkg/engine/context"
|
||||
)
|
||||
|
||||
//NewNotInHandler returns handler to manage NotIn operations
|
||||
func NewNotInHandler(log logr.Logger, ctx context.EvalInterface, subHandler VariableSubstitutionHandler) OperatorHandler {
|
||||
return NotInHandler{
|
||||
ctx: ctx,
|
||||
subHandler: subHandler,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
//NotInHandler provides implementation to handle NotIn Operator
|
||||
type NotInHandler struct {
|
||||
ctx context.EvalInterface
|
||||
subHandler VariableSubstitutionHandler
|
||||
log logr.Logger
|
||||
}
|
||||
|
||||
//Evaluate evaluates expression with NotIn Operator
|
||||
func (nin NotInHandler) Evaluate(key, value interface{}) bool {
|
||||
var err error
|
||||
// substitute the variables
|
||||
if key, err = nin.subHandler(nin.log, nin.ctx, key); err != nil {
|
||||
nin.log.Error(err, "Failed to resolve variable", "variable", key)
|
||||
return false
|
||||
}
|
||||
if value, err = nin.subHandler(nin.log, nin.ctx, value); err != nil {
|
||||
nin.log.Error(err, "Failed to resolve variable", "variable", value)
|
||||
return false
|
||||
}
|
||||
|
||||
switch typedKey := key.(type) {
|
||||
case string:
|
||||
return nin.validateValuewithStringPattern(typedKey, value)
|
||||
default:
|
||||
nin.log.Info("Unsupported type", "value", typedKey, "type", fmt.Sprintf("%T", typedKey))
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if !keyExists {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (nin NotInHandler) validateValuewithBoolPattern(key bool, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (nin NotInHandler) validateValuewithIntPattern(key int64, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (nin NotInHandler) validateValuewithFloatPattern(key float64, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (nin NotInHandler) validateValueWithMapPattern(key map[string]interface{}, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (nin NotInHandler) validateValueWithSlicePattern(key []interface{}, value interface{}) bool {
|
||||
return false
|
||||
}
|
|
@ -30,6 +30,10 @@ func CreateOperatorHandler(log logr.Logger, ctx context.EvalInterface, op kyvern
|
|||
return NewEqualHandler(log, ctx, subHandler)
|
||||
case kyverno.NotEquals:
|
||||
return NewNotEqualHandler(log, ctx, subHandler)
|
||||
case kyverno.In:
|
||||
return NewInHandler(log, ctx, subHandler)
|
||||
case kyverno.NotIn:
|
||||
return NewNotInHandler(log, ctx, subHandler)
|
||||
default:
|
||||
log.Info("operator not supported", "operator", string(op))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue