1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-04-08 10:04:25 +00:00

add negation anchor

This commit is contained in:
shivkumar dudhani 2019-10-10 16:59:08 -07:00
parent 26ffbd29b7
commit f6367cfe4a
3 changed files with 52 additions and 3 deletions
pkg
api/kyverno/v1alpha1
engine

View file

@ -82,3 +82,12 @@ func hasExistingAnchor(str string) (bool, string) {
return (str[:len(left)] == left && str[len(str)-len(right):] == right), str[len(left) : len(str)-len(right)]
}
func hasNegationAnchor(str string) (bool, string) {
left := "X("
right := ")"
if len(str) < len(left)+len(right) {
return false, str
}
return (str[:len(left)] == left && str[len(str)-len(right):] == right), str[len(left) : len(str)-len(right)]
}

View file

@ -21,11 +21,41 @@ func CreateElementHandler(element string, pattern interface{}, path string) Vali
return NewExistanceHandler(element, pattern, path)
case isEqualityAnchor(element):
return NewEqualityHandler(element, pattern, path)
case isNegationAnchor(element):
return NewNegationHandler(element, pattern, path)
default:
return NewDefaultHandler(element, pattern, path)
}
}
func NewNegationHandler(anchor string, pattern interface{}, path string) ValidationHandler {
return NegationHandler{
anchor: anchor,
pattern: pattern,
path: path,
}
}
//NegationHandler provides handler for check if the tag in anchor is not defined
type NegationHandler struct {
anchor string
pattern interface{}
path string
}
//Handle process negation handler
func (nh NegationHandler) Handle(resourceMap map[string]interface{}, originPattern interface{}) (string, error) {
anchorKey := removeAnchor(nh.anchor)
currentPath := nh.path + anchorKey + "/"
// if anchor is present in the resource then fail
if _, ok := resourceMap[anchorKey]; ok {
// no need to process elements in value as key cannot be present in resource
return currentPath, fmt.Errorf("validation rule failed at %s, field %s is disallowed", currentPath, anchorKey)
}
// key is not defined in the resource
return "", nil
}
func NewEqualityHandler(anchor string, pattern interface{}, path string) ValidationHandler {
return EqualityHandler{
anchor: anchor,
@ -150,7 +180,7 @@ func (eh ExistanceHandler) Handle(resourceMap map[string]interface{}, originPatt
case []interface{}:
typedPattern, ok := eh.pattern.([]interface{})
if !ok {
return currentPath, fmt.Errorf("Invalid pattern type %T: Pattern has to be of lis to compare against resource", eh.pattern)
return currentPath, fmt.Errorf("Invalid pattern type %T: Pattern has to be of list to compare against resource", eh.pattern)
}
// get the first item in the pattern array
patternMap := typedPattern[0]
@ -187,7 +217,7 @@ func getAnchorsResourcesFromMap(patternMap map[string]interface{}) (map[string]i
anchors := map[string]interface{}{}
resources := map[string]interface{}{}
for key, value := range patternMap {
if isConditionAnchor(key) || isExistanceAnchor(key) || isEqualityAnchor(key) {
if isConditionAnchor(key) || isExistanceAnchor(key) || isEqualityAnchor(key) || isNegationAnchor(key) {
anchors[key] = value
continue
}

View file

@ -305,6 +305,16 @@ func isEqualityAnchor(str string) bool {
return (str[:len(left)] == left && str[len(str)-len(right):] == right)
}
func isNegationAnchor(str string) bool {
left := "X("
right := ")"
if len(str) < len(left)+len(right) {
return false
}
//TODO: trim spaces ?
return (str[:len(left)] == left && str[len(str)-len(right):] == right)
}
func isAddingAnchor(key string) bool {
const left = "+("
const right = ")"
@ -340,7 +350,7 @@ func removeAnchor(key string) string {
return key[1 : len(key)-1]
}
if isExistanceAnchor(key) || isAddingAnchor(key) || isEqualityAnchor(key) {
if isExistanceAnchor(key) || isAddingAnchor(key) || isEqualityAnchor(key) || isNegationAnchor(key) {
return key[2 : len(key)-1]
}