mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
Merge branch 'develop' into 28-Stateless-policy-engine
This commit is contained in:
commit
b036161f92
2 changed files with 208 additions and 6 deletions
|
@ -4,6 +4,8 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/minio/minio/pkg/wildcard"
|
"github.com/minio/minio/pkg/wildcard"
|
||||||
|
|
||||||
|
@ -11,6 +13,19 @@ import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO: This operators are already implemented in kubernetes
|
||||||
|
type Operator string
|
||||||
|
|
||||||
|
const (
|
||||||
|
MoreEqual Operator = ">="
|
||||||
|
LessEqual Operator = "<="
|
||||||
|
NotEqual Operator = "!="
|
||||||
|
More Operator = ">"
|
||||||
|
Less Operator = "<"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: Refactor using State pattern
|
||||||
|
|
||||||
// Validate handles validating admission request
|
// Validate handles validating admission request
|
||||||
// Checks the target resourse for rules defined in the policy
|
// Checks the target resourse for rules defined in the policy
|
||||||
func Validate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVersionKind) bool {
|
func Validate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVersionKind) bool {
|
||||||
|
@ -58,7 +73,13 @@ func Validate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVers
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateMap(resourcePart, patternPart interface{}) bool {
|
func validateMap(resourcePart, patternPart interface{}) bool {
|
||||||
pattern := patternPart.(map[string]interface{})
|
pattern, ok := patternPart.(map[string]interface{})
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
fmt.Printf("Validating error: expected Map, found %T\n", patternPart)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
resource, ok := resourcePart.(map[string]interface{})
|
resource, ok := resourcePart.(map[string]interface{})
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -80,7 +101,13 @@ func validateMap(resourcePart, patternPart interface{}) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateArray(resourcePart, patternPart interface{}) bool {
|
func validateArray(resourcePart, patternPart interface{}) bool {
|
||||||
patternArray := patternPart.([]interface{})
|
patternArray, ok := patternPart.([]interface{})
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
fmt.Printf("Validating error: expected array, found %T\n", patternPart)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
resourceArray, ok := resourcePart.([]interface{})
|
resourceArray, ok := resourcePart.([]interface{})
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -229,7 +256,60 @@ func checkForWildcard(value, pattern string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkForOperator(value float64, pattern string) bool {
|
func checkForOperator(value float64, pattern string) bool {
|
||||||
return true
|
operators := strings.Split(pattern, "|")
|
||||||
|
|
||||||
|
for _, operator := range operators {
|
||||||
|
operator = strings.Replace(operator, " ", "", -1)
|
||||||
|
if checkSingleOperator(value, operator) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkSingleOperator(value float64, pattern string) bool {
|
||||||
|
if operatorVal, err := strconv.ParseFloat(pattern, 64); err == nil {
|
||||||
|
return value == operatorVal
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(pattern) < 2 {
|
||||||
|
fmt.Printf("Validating error: operator can't have less than 2 characters: %s\n", pattern)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if operatorVal, ok := parseOperator(MoreEqual, pattern); ok {
|
||||||
|
return value >= operatorVal
|
||||||
|
}
|
||||||
|
|
||||||
|
if operatorVal, ok := parseOperator(LessEqual, pattern); ok {
|
||||||
|
return value <= operatorVal
|
||||||
|
}
|
||||||
|
|
||||||
|
if operatorVal, ok := parseOperator(More, pattern); ok {
|
||||||
|
return value > operatorVal
|
||||||
|
}
|
||||||
|
|
||||||
|
if operatorVal, ok := parseOperator(Less, pattern); ok {
|
||||||
|
return value < operatorVal
|
||||||
|
}
|
||||||
|
|
||||||
|
if operatorVal, ok := parseOperator(NotEqual, pattern); ok {
|
||||||
|
return value != operatorVal
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Validating error: unknown operator: %s\n", pattern)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseOperator(operator Operator, pattern string) (float64, bool) {
|
||||||
|
if pattern[:len(operator)] == string(operator) {
|
||||||
|
if value, err := strconv.ParseFloat(pattern[len(operator):len(pattern)], 64); err == nil {
|
||||||
|
return value, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func wrappedWithParentheses(str string) bool {
|
func wrappedWithParentheses(str string) bool {
|
||||||
|
|
|
@ -102,16 +102,138 @@ func TestCheckSingleValue_CheckFloat(t *testing.T) {
|
||||||
assert.Assert(t, !checkSingleValue(value, pattern))
|
assert.Assert(t, !checkSingleValue(value, pattern))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCheckSingleValue_CheckOperatorMore(t *testing.T) {
|
func TestCheckSingleValue_CheckOperatorMoreEqual(t *testing.T) {
|
||||||
pattern := ">10"
|
pattern := " >= 89 "
|
||||||
value := 89
|
value := 89
|
||||||
assert.Assert(t, checkSingleValue(value, pattern))
|
assert.Assert(t, checkSingleValue(value, pattern))
|
||||||
|
|
||||||
pattern = ">10"
|
pattern = ">=10.0001"
|
||||||
floatValue := 89.901
|
floatValue := 89.901
|
||||||
assert.Assert(t, checkSingleValue(floatValue, pattern))
|
assert.Assert(t, checkSingleValue(floatValue, pattern))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCheckSingleValue_CheckOperatorMoreEqualFail(t *testing.T) {
|
||||||
|
pattern := " >= 90 "
|
||||||
|
value := 89
|
||||||
|
assert.Assert(t, !checkSingleValue(value, pattern))
|
||||||
|
|
||||||
|
pattern = ">=910.0001"
|
||||||
|
floatValue := 89.901
|
||||||
|
assert.Assert(t, !checkSingleValue(floatValue, pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckSingleValue_CheckOperatorLessEqual(t *testing.T) {
|
||||||
|
pattern := " <= 1 "
|
||||||
|
value := 1
|
||||||
|
assert.Assert(t, checkSingleValue(value, pattern))
|
||||||
|
|
||||||
|
pattern = "<=10.0001"
|
||||||
|
floatValue := 1.901
|
||||||
|
assert.Assert(t, checkSingleValue(floatValue, pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckSingleValue_CheckOperatorLessEqualFail(t *testing.T) {
|
||||||
|
pattern := " <= 0.1558 "
|
||||||
|
value := 1
|
||||||
|
assert.Assert(t, !checkSingleValue(value, pattern))
|
||||||
|
|
||||||
|
pattern = "<=10.0001"
|
||||||
|
floatValue := 12.901
|
||||||
|
assert.Assert(t, !checkSingleValue(floatValue, pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckSingleValue_CheckOperatorMore(t *testing.T) {
|
||||||
|
pattern := " > 10 "
|
||||||
|
value := 89
|
||||||
|
assert.Assert(t, checkSingleValue(value, pattern))
|
||||||
|
|
||||||
|
pattern = ">10.0001"
|
||||||
|
floatValue := 89.901
|
||||||
|
assert.Assert(t, checkSingleValue(floatValue, pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckSingleValue_CheckOperatorMoreFail(t *testing.T) {
|
||||||
|
pattern := " > 89 "
|
||||||
|
value := 89
|
||||||
|
assert.Assert(t, !checkSingleValue(value, pattern))
|
||||||
|
|
||||||
|
pattern = ">910.0001"
|
||||||
|
floatValue := 89.901
|
||||||
|
assert.Assert(t, !checkSingleValue(floatValue, pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckSingleValue_CheckOperatorLess(t *testing.T) {
|
||||||
|
pattern := " < 10 "
|
||||||
|
value := 9
|
||||||
|
assert.Assert(t, checkSingleValue(value, pattern))
|
||||||
|
|
||||||
|
pattern = "<10.0001"
|
||||||
|
floatValue := 9.901
|
||||||
|
assert.Assert(t, checkSingleValue(floatValue, pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckSingleValue_CheckOperatorLessFail(t *testing.T) {
|
||||||
|
pattern := " < 10 "
|
||||||
|
value := 10
|
||||||
|
assert.Assert(t, !checkSingleValue(value, pattern))
|
||||||
|
|
||||||
|
pattern = "<10.0001"
|
||||||
|
floatValue := 19.901
|
||||||
|
assert.Assert(t, !checkSingleValue(floatValue, pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckSingleValue_CheckOperatorNotEqual(t *testing.T) {
|
||||||
|
pattern := " != 10 "
|
||||||
|
value := 9.99999
|
||||||
|
assert.Assert(t, checkSingleValue(value, pattern))
|
||||||
|
|
||||||
|
pattern = "!=10.0001"
|
||||||
|
floatValue := 10.0000
|
||||||
|
assert.Assert(t, checkSingleValue(floatValue, pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckSingleValue_CheckOperatorNotEqualFail(t *testing.T) {
|
||||||
|
pattern := " != 9.99999 "
|
||||||
|
value := 9.99999
|
||||||
|
assert.Assert(t, !checkSingleValue(value, pattern))
|
||||||
|
|
||||||
|
pattern = "!=10"
|
||||||
|
floatValue := 10
|
||||||
|
assert.Assert(t, !checkSingleValue(floatValue, pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckSingleValue_CheckOperatorEqual(t *testing.T) {
|
||||||
|
pattern := " 10.000001 "
|
||||||
|
value := 10.000001
|
||||||
|
assert.Assert(t, checkSingleValue(value, pattern))
|
||||||
|
|
||||||
|
pattern = "10.000000"
|
||||||
|
floatValue := 10
|
||||||
|
assert.Assert(t, checkSingleValue(floatValue, pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckSingleValue_CheckOperatorEqualFail(t *testing.T) {
|
||||||
|
pattern := " 10.000000 "
|
||||||
|
value := 10.000001
|
||||||
|
assert.Assert(t, !checkSingleValue(value, pattern))
|
||||||
|
|
||||||
|
pattern = "10.000001"
|
||||||
|
floatValue := 10
|
||||||
|
assert.Assert(t, !checkSingleValue(floatValue, pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckSingleValue_CheckSeveralOperators(t *testing.T) {
|
||||||
|
pattern := " <-1 | 10.000001 "
|
||||||
|
value := 10.000001
|
||||||
|
assert.Assert(t, checkSingleValue(value, pattern))
|
||||||
|
|
||||||
|
value = -30
|
||||||
|
assert.Assert(t, checkSingleValue(value, pattern))
|
||||||
|
|
||||||
|
value = 5
|
||||||
|
assert.Assert(t, !checkSingleValue(value, pattern))
|
||||||
|
}
|
||||||
|
|
||||||
func TestCheckSingleValue_CheckWildcard(t *testing.T) {
|
func TestCheckSingleValue_CheckWildcard(t *testing.T) {
|
||||||
pattern := "nirmata_*"
|
pattern := "nirmata_*"
|
||||||
value := "nirmata_awesome"
|
value := "nirmata_awesome"
|
||||||
|
|
Loading…
Add table
Reference in a new issue