Repository: kyverno/kyverno (go)

Issue:
[BUG] Wildcards are ignored when occuring in lists/arrays
**Software version numbers**
State the version numbers of applications involved in the bug.

* Kubernetes version: 1.21
* Kubernetes platform (if applicable; ex., EKS, GKE, OpenShift): K3d
* Kyverno version: 1.6.0-ish

```json
[
  "ghcr.io/kyverno/kyverno:latest@sha256:a78a24b758a2e4fd88edd02ccc242dad503fb083a46839dd5c6d14b77a1ad218",
  "ghcr.io/kyverno/kyvernopre:latest@sha256:1124d52b6363bdbe6a9a8c910786ce7f3b1c90ca400f4f65f88d44df6947e41c"
]
```

**Describe the bug**
The `NotIn` operator (assumed to be others) does not see wildcards when the value is given in array format, only if given in string.

**To Reproduce**
Steps to reproduce the behavior:
1. Apply this policy:

```yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: poc-array-wildcards
spec:
  validationFailureAction: enforce
  background: false
  rules:
    - name: wildcards
      match:
        resources:
          kinds:
          - Pod
      validate:
        message: This Pod names an image that is not from an approved registry.
        foreach:
        - list: "request.object.spec.[initContainers, ephemeralContainers, containers][]"
          deny:
            conditions:
              all:
                - key: "{{element.image}}"
                  operator: NotIn
                  value: registry.corp/*
```
2. Create this sample Pod resource:

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  automountServiceAccountToken: false
  containers:
  - name: busybox
    image: registry.corp/sdf3vhadfa:1.28
```

3. Observe the Pod is allowed to be created:

```sh
$ k apply -f poc-pod.yaml
pod/mypod created
```
4. Modify the ClusterPolicy to place the value `registry.corp/*` into either a list or JSON-encoded array:

```yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: poc-array-wildcards
spec:
  validationFailureAction: enforce
  background: false
  rules:
    - name: wildcards
      match:
        resources:
          kinds:
          - Pod
      validate:
        message: This Pod names an image that is not from an approved registry.
        foreach:
        - list: "request.object.spec.[initContainers, ephemeralContainers, containers][]"
          deny:
            conditions:
              all:
                - key: "{{element.image}}"
                  operator: NotIn
                  value:
                  - registry.corp/*
```

5. Try to create the same Pod. This should still be allowed yet it is now blocked.

```sh
$ k apply -f poc-pod.yaml 
Error from server: error when creating "poc-pod.yaml": admission webhook "validate.kyverno.svc-fail" denied the request: 

resource Pod/default/mypod was blocked due to the following policies

poc-array-wildcards:
  wildcards: validation failed in foreach rule for This Pod names an image that is
    not from an approved registry.
```

**Expected behavior**
The Pod is allowed in both variations of the policy because the value against which the image is being compared is a wildcard value and the pattern matches.

**Additional context**
This is related to the work @anushkamittal20 has done in PR https://github.com/kyverno/kyverno/pull/2692


Pull request description:
Extend new operators
## Related issue
#2734 
Resolves #2813 
<!--
Please link the GitHub issue this pull request resolves in the format of `#1234`. If you discussed this change
with a maintainer, please mention her/him using the `@` syntax (e.g. `@JimBugwadia`).

If this change neither resolves an existing issue nor has sign-off from one of the maintainers, there is a
chance substantial changes will be requested or that the changes will be rejected.

You can discuss changes with maintainers in the [Kyverno Slack Channel](https://kubernetes.slack.com/).
-->

## Milestone of this PR
/milestone 1.6.0
<!--

Add the milestone label by commenting `/milestone 1.2.3`.

-->
## What type of PR is this
> /kind feature
<!--

> Uncomment only one ` /kind <>` line, hit enter to put that in a new line, and remove leading white spaces from that line:
>
> /kind api-change
> /kind bug
> /kind cleanup
> /kind design
> /kind documentation
> /kind failing-test
> /kind feature
-->

## Proposed Changes
We have added  checking the range of numbers in the new operators i.e. `AnyIn`, `AnyNotIn`, `AllIn`, `AllNotIn` this allows user to check conditions/preconditions whether a numeric value(key) is present in 
a range (value) 
<!--
Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. 

***NOTE***: If this PR results in new or altered behavior which is user facing, you **MUST** read and follow the steps outlined in the [PR documentation guide](pr_documentation.md) and add Proof Manifests as defined below.
-->

### Proof Manifests
```
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: drop-cap-net-raw
spec:
  validationFailureAction: enforce
  background: false
  rules:
  - name: drop-cap-net-raw
    match:
      resources:
        kinds:
        - Pod
    validate:
      deny:
        conditions:
          any:
          - key: 
            - 30
            - 40
            operator: AnyIn
            value: 10-100
```
```
apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
  - name: test
    image: defdasdabian:923
```
this policy will deny the pod
<!--
Read and follow the [PR documentation guide](https://github.com/kyverno/kyverno/blob/main/.github/pr_documentation.md) for more details first. This section is for pasting your YAML manifests (Kubernetes resources and Kyverno policies) and Kyverno CLI test manifests which allow maintainers to prove the intended functionality is achieved by your PR. Please use proper fenced code block formatting, for example:

# Kubernetes resource

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: roles-dictionary
  namespace: default
data:
  allowed-roles: "[\"cluster-admin\", \"cluster-operator\", \"tenant-admin\"]"
```

# Kyverno CLI test manifest (please see docs for latest manifest format at https://kyverno.io/docs/kyverno-cli/). See kyverno/policies for complete examples of all related test files.

```yaml
name: prepend-image-registry
policies:
  - prepend_image_registry.yaml
resources:
  - resource.yaml
variables: values.yaml
results:
  - policy: prepend-registry
    rule: prepend-registry-containers
    resource: mypod
    # if mutate rule
    patchedResource: patchedResource01.yaml
    kind: Pod
    result: pass
```
-->

## Checklist

<!--
Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of
them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.
-->

- [x] I have read the [contributing guidelines](https://github.com/kyverno/kyverno/blob/main/CONTRIBUTING.md).
- [x] I have added tests that prove my fix is effective or that my feature works.
- [] My PR contains new or altered behavior to Kyverno and
  - [] CLI support should be added my PR doesn't contain that functionality.
  - [] I have added or changed [the documentation](https://github.com/kyverno/website) myself in an existing PR and the link is:
  <!-- Uncomment to link to the PR -->
  <!-- https://github.com/kyverno/website/pull/123 -->
  - [] I have raised an issue in [kyverno/website](https://github.com/kyverno/website) to track the doc update and the link is:
  <!-- Uncomment to link to the issue -->
  <!-- https://github.com/kyverno/website/issues/1 -->
  - [] I have read the [PR documentation guide](https://github.com/kyverno/kyverno/blob/main/.github/pr_documentation.md) and followed the process including adding proof manifests to this PR.

## Further Comments

<!--
If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution
you did and what alternatives you considered, etc...
-->


Patch:
diff --git a/pkg/engine/validate/common.go b/pkg/engine/common/common.go
similarity index 97%
rename from pkg/engine/validate/common.go
rename to pkg/engine/common/common.go
index 9e4e58118..4f78c7ee6 100644
--- a/pkg/engine/validate/common.go
+++ b/pkg/engine/common/common.go
@@ -1,4 +1,4 @@
-package validate
+package common
 
 import (
 	"fmt"
diff --git a/pkg/engine/validate/pattern.go b/pkg/engine/common/pattern.go
similarity index 99%
rename from pkg/engine/validate/pattern.go
rename to pkg/engine/common/pattern.go
index 40bed7980..a4e0c282b 100644
--- a/pkg/engine/validate/pattern.go
+++ b/pkg/engine/common/pattern.go
@@ -1,4 +1,4 @@
-package validate
+package common
 
 import (
 	"fmt"
diff --git a/pkg/engine/mutate/overlayCondition.go b/pkg/engine/mutate/overlayCondition.go
index 0b18a4b53..69d247d98 100755
--- a/pkg/engine/mutate/overlayCondition.go
+++ b/pkg/engine/mutate/overlayCondition.go
@@ -7,7 +7,7 @@ import (
 
 	"github.com/go-logr/logr"
 	commonAnchors "github.com/kyverno/kyverno/pkg/engine/anchor/common"
-	"github.com/kyverno/kyverno/pkg/engine/validate"
+	"github.com/kyverno/kyverno/pkg/engine/common"
 	"sigs.k8s.io/controller-runtime/pkg/log"
 )
 
@@ -144,7 +144,7 @@ func compareOverlay(resource, overlay interface{}, path string) (string, overlay
 			}
 		}
 	case string, float64, int, int64, bool, nil:
-		if !validate.ValidateValueWithPattern(log.Log, resource, overlay) {
+		if !common.ValidateValueWithPattern(log.Log, resource, overlay) {
 			log.Log.V(4).Info(fmt.Sprintf("Mutate rule: failed validating value %v with overlay %v", resource, overlay))
 			return path, newOverlayError(conditionFailure, fmt.Sprintf("Failed validating value %v with overlay %v", resource, overlay))
 		}
diff --git a/pkg/engine/validate/validate.go b/pkg/engine/validate/validate.go
index cffe2aca6..d8d488c47 100644
--- a/pkg/engine/validate/validate.go
+++ b/pkg/engine/validate/validate.go
@@ -79,13 +79,13 @@ func validateResourceElement(log logr.Logger, resourceElement, patternElement, o
 		switch resource := resourceElement.(type) {
 		case []interface{}:
 			for _, res := range resource {
-				if !ValidateValueWithPattern(log, res, patternElement) {
+				if !common.ValidateValueWithPattern(log, res, patternElement) {
 					return path, fmt.Errorf("resource value '%v' does not match '%v' at path %s", resourceElement, patternElement, path)
 				}
 			}
 			return "", nil
 		default:
-			if !ValidateValueWithPattern(log, resourceElement, patternElement) {
+			if !common.ValidateValueWithPattern(log, resourceElement, patternElement) {
 				return path, fmt.Errorf("resource value '%v' does not match '%v' at path %s", resourceElement, patternElement, path)
 			}
 		}
diff --git a/pkg/engine/variables/operator/allin.go b/pkg/engine/variables/operator/allin.go
index 4c6cb77be..a3626d49c 100644
--- a/pkg/engine/variables/operator/allin.go
+++ b/pkg/engine/variables/operator/allin.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/go-logr/logr"
 	"github.com/kyverno/kyverno/pkg/engine/context"
+	"github.com/kyverno/kyverno/pkg/engine/operator"
 	"github.com/minio/pkg/wildcard"
 )
 
@@ -28,6 +29,8 @@ func (allin AllInHandler) Evaluate(key, value interface{}) bool {
 	switch typedKey := key.(type) {
 	case string:
 		return allin.validateValueWithStringPattern(typedKey, value)
+	case int, int32, int64, float32, float64:
+		return allin.validateValueWithStringPattern(fmt.Sprint(typedKey), value)
 	case []interface{}:
 		var stringSlice []string
 		for _, v := range typedKey {
@@ -41,7 +44,7 @@ func (allin AllInHandler) Evaluate(key, value interface{}) bool {
 }
 
 func (allin AllInHandler) validateValueWithStringPattern(key string, value interface{}) (keyExists bool) {
-	invalidType, keyExists := keyExistsInArray(key, value, allin.log)
+	invalidType, keyExists := allKeyExistsInArray(key, value, allin.log)
 	if invalidType {
 		allin.log.Info("expected type []string", "value", value, "type", fmt.Sprintf("%T", value))
 		return false
@@ -50,6 +53,49 @@ func (allin AllInHandler) validateValueWithStringPattern(key string, value inter
 	return keyExists
 }
 
+func allKeyExistsInArray(key string, value interface{}, log logr.Logger) (invalidType bool, keyExists bool) {
+	switch valuesAvailable := value.(type) {
+
+	case []interface{}:
+		for _, val := range valuesAvailable {
+			if wildcard.Match(key, fmt.Sprint(val)) {
+				return false, true
+			}
+		}
+
+	case string:
+		if wildcard.Match(valuesAvailable, key) {
+			return false, true
+		}
+
+		operatorVariable := operator.GetOperatorFromStringPattern(fmt.Sprintf("%v", value))
+		if operatorVariable == operator.InRange {
+			return false, handleRange(key, value, log)
+		}
+
+		var arr []string
+		if json.Valid([]byte(valuesAvailable)) {
+			if err := json.Unmarshal([]byte(valuesAvailable), &arr); err != nil {
+				log.Error(err, "failed to unmarshal value to JSON string array", "key", key, "value", value)
+				return true, false
+			}
+		} else {
+			arr = append(arr, valuesAvailable)
+		}
+
+		for _, val := range arr {
+			if key == val {
+				return false, true
+			}
+		}
+
+	default:
+		return true, false
+	}
+
+	return false, false
+}
+
 func (allin AllInHandler) validateValueWithStringSetPattern(key []string, value interface{}) (keyExists bool) {
 	invalidType, isAllIn := allSetExistsInArray(key, value, allin.log, false)
 	if invalidType {
@@ -80,9 +126,36 @@ func allSetExistsInArray(key []string, value interface{}, log logr.Logger, allNo
 	case string:
 
 		if len(key) == 1 && key[0] == valuesAvailable {
+			if allNotIn {
+				return false, false
+			}
 			return false, true
 		}
 
+		operatorVariable := operator.GetOperatorFromStringPattern(fmt.Sprintf("%v", value))
+		if operatorVariable == operator.InRange {
+			if allNotIn {
+				isAllNotInBool := true
+				for _, k := range key {
+					if handleRange(k, valuesAvailable, log) {
+						isAllNotInBool = false
+					}
+				}
+				return false, isAllNotInBool
+			} else {
+				isAllInCount := 0
+				for _, k := range key {
+					if handleRange(k, value, log) {
+						isAllInCount++
+					}
+				}
+				if isAllInCount == len(key) {
+					return false, true
+				}
+				return false, false
+			}
+		}
+
 		var arr []string
 		if json.Valid([]byte(valuesAvailable)) {
 			if err := json.Unmarshal([]byte(valuesAvailable), &arr); err != nil {
diff --git a/pkg/engine/variables/operator/allnotin.go b/pkg/engine/variables/operator/allnotin.go
index ab5f8e152..16745da35 100644
--- a/pkg/engine/variables/operator/allnotin.go
+++ b/pkg/engine/variables/operator/allnotin.go
@@ -41,7 +41,7 @@ func (allnin AllNotInHandler) Evaluate(key, value interface{}) bool {
 }
 
 func (allnin AllNotInHandler) validateValueWithStringPattern(key string, value interface{}) bool {
-	invalidType, keyExists := keyExistsInArray(key, value, allnin.log)
+	invalidType, keyExists := allKeyExistsInArray(key, value, allnin.log)
 	if invalidType {
 		allnin.log.Info("expected type []string", "value", value, "type", fmt.Sprintf("%T", value))
 		return false
diff --git a/pkg/engine/variables/operator/anyin.go b/pkg/engine/variables/operator/anyin.go
index fcbce5ad2..b90d6f950 100644
--- a/pkg/engine/variables/operator/anyin.go
+++ b/pkg/engine/variables/operator/anyin.go
@@ -3,9 +3,12 @@ package operator
 import (
 	"encoding/json"
 	"fmt"
+	"strings"
 
 	"github.com/go-logr/logr"
+	"github.com/kyverno/kyverno/pkg/engine/common"
 	"github.com/kyverno/kyverno/pkg/engine/context"
+	"github.com/kyverno/kyverno/pkg/engine/operator"
 	"github.com/minio/pkg/wildcard"
 )
 
@@ -43,7 +46,7 @@ func (anyin AnyInHandler) Evaluate(key, value interface{}) bool {
 }
 
 func (anyin AnyInHandler) validateValueWithStringPattern(key string, value interface{}) (keyExists bool) {
-	invalidType, keyExists := keyExistsInArray(key, value, anyin.log)
+	invalidType, keyExists := anyKeyExistsInArray(key, value, anyin.log)
 	if invalidType {
 		anyin.log.Info("expected type []string", "value", value, "type", fmt.Sprintf("%T", value))
 		return false
@@ -52,6 +55,60 @@ func (anyin AnyInHandler) validateValueWithStringPattern(key string, value inter
 	return keyExists
 }
 
+// anykeyExistsInArray checks if the  key exists in the array value
+// The value can be a string, an array of strings, or a JSON format
+// array of strings (e.g. ["val1", "val2", "val3"].
+func anyKeyExistsInArray(key string, value interface{}, log logr.Logger) (invalidType bool, keyExists bool) {
+	switch valuesAvailable := value.(type) {
+
+	case []interface{}:
+		for _, val := range valuesAvailable {
+			if wildcard.Match(key, fmt.Sprint(val)) {
+				return false, true
+			}
+		}
+
+	case string:
+		if wildcard.Match(valuesAvailable, key) {
+			return false, true
+		}
+
+		operatorVariable := operator.GetOperatorFromStringPattern(fmt.Sprintf("%v", value))
+		if operatorVariable == operator.InRange {
+			return false, handleRange(key, value, log)
+		}
+
+		var arr []string
+		if json.Valid([]byte(valuesAvailable)) {
+			if err := json.Unmarshal([]byte(valuesAvailable), &arr); err != nil {
+				log.Error(err, "failed to unmarshal value to JSON string array", "key", key, "value", value)
+				return true, false
+			}
+		} else {
+			arr = append(arr, valuesAvailable)
+		}
+
+		for _, val := range arr {
+			if key == val {
+				return false, true
+			}
+		}
+
+	default:
+		return true, false
+	}
+
+	return false, false
+}
+
+func handleRange(key string, value interface{}, log logr.Logger) bool {
+	if !common.ValidateValueWithPattern(log, key, value) {
+		return false
+	} else {
+		return true
+	}
+}
+
 func (anyin AnyInHandler) validateValueWithStringSetPattern(key []string, value interface{}) (keyExists bool) {
 	invalidType, isAnyIn := anySetExistsInArray(key, value, anyin.log, false)
 	if invalidType {
@@ -80,11 +137,37 @@ func anySetExistsInArray(key []string, value interface{}, log logr.Logger, anyNo
 		return false, isAnyIn(key, valueSlice)
 
 	case string:
-
 		if len(key) == 1 && key[0] == valuesAvailable {
+			if anyNotIn {
+				return false, false
+			}
 			return false, true
 		}
 
+		operatorVariable := operator.GetOperatorFromStringPattern(fmt.Sprintf("%v", value))
+		if operatorVariable == operator.InRange {
+			if anyNotIn {
+				isAnyNotInBool := false
+				stringForAnyNotIn := strings.Replace(valuesAvailable, "-", "!-", 1)
+				for _, k := range key {
+					if handleRange(k, stringForAnyNotIn, log) {
+						isAnyNotInBool = true
+						break
+					}
+				}
+				return false, isAnyNotInBool
+			} else {
+				isAnyInBool := false
+				for _, k := range key {
+					if handleRange(k, value, log) {
+						isAnyInBool = true
+						break
+					}
+				}
+				return false, isAnyInBool
+			}
+		}
+
 		var arr []string
 		if json.Valid([]byte(valuesAvailable)) {
 			if err := json.Unmarshal([]byte(valuesAvailable), &arr); err != nil {
diff --git a/pkg/engine/variables/operator/anynotin.go b/pkg/engine/variables/operator/anynotin.go
index 8a6db53f3..257b71f8e 100644
--- a/pkg/engine/variables/operator/anynotin.go
+++ b/pkg/engine/variables/operator/anynotin.go
@@ -41,7 +41,7 @@ func (anynin AnyNotInHandler) Evaluate(key, value interface{}) bool {
 }
 
 func (anynin AnyNotInHandler) validateValueWithStringPattern(key string, value interface{}) bool {
-	invalidType, keyExists := keyExistsInArray(key, value, anynin.log)
+	invalidType, keyExists := anyKeyExistsInArray(key, value, anynin.log)
 	if invalidType {
 		anynin.log.Info("expected type []string", "value", value, "type", fmt.Sprintf("%T", value))
 		return false
diff --git a/pkg/generate/validate.go b/pkg/generate/validate.go
index 6047e814c..2798a0934 100644
--- a/pkg/generate/validate.go
+++ b/pkg/generate/validate.go
@@ -6,7 +6,7 @@ import (
 	"strconv"
 
 	"github.com/go-logr/logr"
-	"github.com/kyverno/kyverno/pkg/engine/validate"
+	"github.com/kyverno/kyverno/pkg/engine/common"
 	"github.com/kyverno/kyverno/pkg/engine/wildcards"
 	"sigs.k8s.io/controller-runtime/pkg/log"
 )
@@ -54,7 +54,7 @@ func validateResourceElement(log logr.Logger, resourceElement, patternElement, o
 		return validateArray(log, typedResourceElement, typedPatternElement, originPattern, path)
 	// elementary values
 	case string, float64, int, int64, bool, nil:
-		if !validate.ValidateValueWithPattern(log, resourceElement, patternElement) {
+		if !common.ValidateValueWithPattern(log, resourceElement, patternElement) {
 			return path, fmt.Errorf("value '%v' does not match '%v' at path %s", resourceElement, patternElement, path)
 		}
 


Test patch:
diff --git a/pkg/engine/validate/pattern_test.go b/pkg/engine/common/pattern_test.go
similarity index 99%
rename from pkg/engine/validate/pattern_test.go
rename to pkg/engine/common/pattern_test.go
index 200afd798..21de14523 100644
--- a/pkg/engine/validate/pattern_test.go
+++ b/pkg/engine/common/pattern_test.go
@@ -1,4 +1,4 @@
-package validate
+package common
 
 import (
 	"encoding/json"
diff --git a/pkg/engine/variables/evaluate_test.go b/pkg/engine/variables/evaluate_test.go
index aae7ea610..96aee93a8 100644
--- a/pkg/engine/variables/evaluate_test.go
+++ b/pkg/engine/variables/evaluate_test.go
@@ -291,6 +291,12 @@ func TestEvaluate(t *testing.T) {
 		{kyverno.Condition{Key: []interface{}{"5*"}, Operator: kyverno.ConditionOperators["AnyIn"], Value: []interface{}{"1.1.1.1", "2.2.2.2", "3.3.3.3"}}, false},
 		{kyverno.Condition{Key: []interface{}{"1.1.1.1", "2.2.2.2", "5.5.5.5"}, Operator: kyverno.ConditionOperators["AnyIn"], Value: []interface{}{"2*"}}, true},
 		{kyverno.Condition{Key: []interface{}{"1.1.1.1", "2.2.2.2", "5.5.5.5"}, Operator: kyverno.ConditionOperators["AnyIn"], Value: []interface{}{"4*"}}, false},
+		{kyverno.Condition{Key: []interface{}{"5"}, Operator: kyverno.ConditionOperators["AnyIn"], Value: "1-3"}, false},
+		{kyverno.Condition{Key: "5", Operator: kyverno.ConditionOperators["AnyIn"], Value: "1-10"}, true},
+		{kyverno.Condition{Key: 5, Operator: kyverno.ConditionOperators["AnyIn"], Value: "1-10"}, true},
+		{kyverno.Condition{Key: []interface{}{1, 5}, Operator: kyverno.ConditionOperators["AnyIn"], Value: "7-10"}, false},
+		{kyverno.Condition{Key: []interface{}{1, 5}, Operator: kyverno.ConditionOperators["AnyIn"], Value: "0-10"}, true},
+		{kyverno.Condition{Key: []interface{}{1.002, 1.222}, Operator: kyverno.ConditionOperators["AnyIn"], Value: "1.001-10"}, true},
 
 		// All In
 		{kyverno.Condition{Key: []interface{}{"1.1.1.1", "2.2.2.2"}, Operator: kyverno.ConditionOperators["AllIn"], Value: []interface{}{"1.1.1.1", "2.2.2.2", "3.3.3.3"}}, true},
@@ -305,6 +311,9 @@ func TestEvaluate(t *testing.T) {
 		{kyverno.Condition{Key: []interface{}{"2.1.1.1", "2.2.2.2", "2.5.5.5"}, Operator: kyverno.ConditionOperators["AllIn"], Value: []interface{}{"2*"}}, true},
 		{kyverno.Condition{Key: []interface{}{"1.1.1.1", "2.2.2.2", "5.5.5.5"}, Operator: kyverno.ConditionOperators["AllIn"], Value: []interface{}{"4*"}}, false},
 		{kyverno.Condition{Key: []interface{}{"1.1.1.1", "5.5.5.5"}, Operator: kyverno.ConditionOperators["AllIn"], Value: "5.5.5.5"}, false},
+		{kyverno.Condition{Key: 5, Operator: kyverno.ConditionOperators["AllIn"], Value: "1-10"}, true},
+		{kyverno.Condition{Key: []interface{}{3, 2}, Operator: kyverno.ConditionOperators["AllIn"], Value: "1-10"}, true},
+		{kyverno.Condition{Key: []interface{}{3, 2}, Operator: kyverno.ConditionOperators["AllIn"], Value: "5-10"}, false},
 
 		// All Not In
 		{kyverno.Condition{Key: 1, Operator: kyverno.ConditionOperators["AllNotIn"], Value: []interface{}{1, 2, 3}}, false},
@@ -323,6 +332,10 @@ func TestEvaluate(t *testing.T) {
 		{kyverno.Condition{Key: []interface{}{"1.1.1.1", "3.3.3.3", "5.5.5.5"}, Operator: kyverno.ConditionOperators["AllNotIn"], Value: []interface{}{"2*"}}, true},
 		{kyverno.Condition{Key: []interface{}{"4.1.1.1", "4.2.2.2", "4.5.5.5"}, Operator: kyverno.ConditionOperators["AllNotIn"], Value: []interface{}{"4*"}}, false},
 		{kyverno.Condition{Key: []interface{}{"1.1.1.1", "4.4.4.4"}, Operator: kyverno.ConditionOperators["AllNotIn"], Value: "2.2.2.2"}, true},
+		{kyverno.Condition{Key: 5.5, Operator: kyverno.ConditionOperators["AllNotIn"], Value: "6-10"}, true},
+		{kyverno.Condition{Key: "5", Operator: kyverno.ConditionOperators["AllNotIn"], Value: "1-6"}, false},
+		{kyverno.Condition{Key: []interface{}{3, 2}, Operator: kyverno.ConditionOperators["AllNotIn"], Value: "5-10"}, true},
+		{kyverno.Condition{Key: []interface{}{2, 6}, Operator: kyverno.ConditionOperators["AllNotIn"], Value: "5-10"}, false},
 
 		// Any Not In
 		{kyverno.Condition{Key: 1, Operator: kyverno.ConditionOperators["AnyNotIn"], Value: []interface{}{1, 2, 3}}, false},
@@ -338,6 +351,9 @@ func TestEvaluate(t *testing.T) {
 		{kyverno.Condition{Key: []interface{}{"1*", "3*", "5*"}, Operator: kyverno.ConditionOperators["AnyNotIn"], Value: []interface{}{"1.1.1.1", "2.2.2.2", "3.3.3.3"}}, true},
 		{kyverno.Condition{Key: []interface{}{"1.1.1.1", "2.2.2.2", "5.5.5.5"}, Operator: kyverno.ConditionOperators["AnyNotIn"], Value: []interface{}{"2*"}}, true},
 		{kyverno.Condition{Key: []interface{}{"2.2*"}, Operator: kyverno.ConditionOperators["AnyNotIn"], Value: []interface{}{"2.2.2.2"}}, false},
+		{kyverno.Condition{Key: "5", Operator: kyverno.ConditionOperators["AnyNotIn"], Value: "1-3"}, true},
+		{kyverno.Condition{Key: []interface{}{1, 5, 11}, Operator: kyverno.ConditionOperators["AnyNotIn"], Value: "0-10"}, true},
+		{kyverno.Condition{Key: []interface{}{1, 5, 7}, Operator: kyverno.ConditionOperators["AnyNotIn"], Value: "0-10"}, false},
 	}
 
 	ctx := context.NewContext()