mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
add messages and set rule to skip when pattern does not match
Signed-off-by: Jim Bugwadia <jim@nirmata.com>
This commit is contained in:
parent
6ae3063038
commit
1ebd2c99f2
3 changed files with 44 additions and 24 deletions
|
@ -335,7 +335,7 @@ func checkCondition(logger logr.Logger, pattern *yaml.RNode, resource *yaml.RNod
|
|||
return err
|
||||
}
|
||||
|
||||
err, _ = validate.MatchPattern(logger, resourceInterface, patternInterface)
|
||||
err = validate.MatchPattern(logger, resourceInterface, patternInterface)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -12,9 +12,24 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/engine/wildcards"
|
||||
)
|
||||
|
||||
|
||||
type PatternError struct {
|
||||
Err error
|
||||
Path string
|
||||
Skip bool
|
||||
}
|
||||
|
||||
func (e *PatternError) Error() string {
|
||||
if e.Err == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return e.Err.Error()
|
||||
}
|
||||
|
||||
// MatchPattern is a start of element-by-element pattern validation process.
|
||||
// It assumes that validation is started from root, so "/" is passed
|
||||
func MatchPattern(logger logr.Logger, resource, pattern interface{}) (error, string) {
|
||||
func MatchPattern(logger logr.Logger, resource, pattern interface{}) error {
|
||||
// newAnchorMap - to check anchor key has values
|
||||
ac := common.NewAnchorMap()
|
||||
elemPath, err := validateResourceElement(logger, resource, pattern, pattern, "/", ac)
|
||||
|
@ -22,19 +37,19 @@ func MatchPattern(logger logr.Logger, resource, pattern interface{}) (error, str
|
|||
// if conditional or global anchors report errors, the rule does not apply to the resource
|
||||
if common.IsConditionalAnchorError(err.Error()) || common.IsGlobalAnchorError(err.Error()) {
|
||||
logger.V(3).Info("skipping resource as anchor does not apply", "msg", ac.AnchorError.Error())
|
||||
return nil, ""
|
||||
return &PatternError{nil, "", true}
|
||||
}
|
||||
|
||||
// check if an anchor defined in the policy rule is missing in the resource
|
||||
if ac.IsAnchorError() {
|
||||
logger.V(3).Info("missing anchor in resource")
|
||||
return err, ""
|
||||
return &PatternError{err, "", false}
|
||||
}
|
||||
|
||||
return err, elemPath
|
||||
return &PatternError{err, elemPath, false}
|
||||
}
|
||||
|
||||
return nil, ""
|
||||
return &PatternError{nil, "", false}
|
||||
}
|
||||
|
||||
// validateResourceElement detects the element type (map, array, nil, string, int, bool, float)
|
||||
|
|
|
@ -193,7 +193,7 @@ func (v *validator) validate() *response.RuleResponse {
|
|||
if err != nil {
|
||||
return ruleError(v.rule, "failed to evaluate preconditions", err)
|
||||
} else if !preconditionsPassed {
|
||||
return ruleResponse(v.rule, "", response.RuleStatusSkip)
|
||||
return ruleResponse(v.rule, "preconditions not met", response.RuleStatusSkip)
|
||||
}
|
||||
|
||||
if v.pattern != nil || v.anyPattern != nil {
|
||||
|
@ -222,7 +222,7 @@ func (v *validator) validateForEach() *response.RuleResponse {
|
|||
if err != nil {
|
||||
return ruleError(v.rule, "failed to evaluate preconditions", err)
|
||||
} else if !preconditionsPassed {
|
||||
return ruleResponse(v.rule, "", response.RuleStatusSkip)
|
||||
return ruleResponse(v.rule, "preconditions not met", response.RuleStatusSkip)
|
||||
}
|
||||
|
||||
foreach := v.rule.Validation.ForEachValidation
|
||||
|
@ -266,10 +266,10 @@ func (v *validator) validateForEach() *response.RuleResponse {
|
|||
}
|
||||
|
||||
if applyCount == 0 {
|
||||
return ruleResponse(v.rule, "", response.RuleStatusSkip)
|
||||
return ruleResponse(v.rule, "rule skipped", response.RuleStatusSkip)
|
||||
}
|
||||
|
||||
return ruleResponse(v.rule, "", response.RuleStatusPass)
|
||||
return ruleResponse(v.rule, "rule passed", response.RuleStatusPass)
|
||||
}
|
||||
|
||||
func addElementToContext(ctx *PolicyContext, e interface{}) error {
|
||||
|
@ -436,13 +436,16 @@ func isSameRuleResponse(r1 *response.RuleResponse, r2 *response.RuleResponse) bo
|
|||
// validatePatterns validate pattern and anyPattern
|
||||
func (v *validator) validatePatterns(resource unstructured.Unstructured) *response.RuleResponse {
|
||||
if v.pattern != nil {
|
||||
if err, path := validate.MatchPattern(v.log, resource.Object, v.pattern); err != nil {
|
||||
v.log.V(3).Info("validation error", "path", path, "error", err.Error())
|
||||
if path == "" {
|
||||
return ruleResponse(v.rule, v.buildErrorMessage(err, ""), response.RuleStatusError)
|
||||
}
|
||||
if err := validate.MatchPattern(v.log, resource.Object, v.pattern); err != nil {
|
||||
|
||||
return ruleResponse(v.rule, v.buildErrorMessage(err, path), response.RuleStatusFail)
|
||||
if pe, ok := err.(*validate.PatternError); ok{
|
||||
v.log.V(3).Info("validation error", "path", pe.Path, "error", err.Error())
|
||||
if pe.Path == "" {
|
||||
return ruleResponse(v.rule, v.buildErrorMessage(err, ""), response.RuleStatusError)
|
||||
}
|
||||
|
||||
return ruleResponse(v.rule, v.buildErrorMessage(err, pe.Path), response.RuleStatusFail)
|
||||
}
|
||||
}
|
||||
|
||||
v.log.V(4).Info("successfully processed rule")
|
||||
|
@ -461,19 +464,21 @@ func (v *validator) validatePatterns(resource unstructured.Unstructured) *respon
|
|||
}
|
||||
|
||||
for idx, pattern := range anyPatterns {
|
||||
err, path := validate.MatchPattern(v.log, resource.Object, pattern)
|
||||
err := validate.MatchPattern(v.log, resource.Object, pattern)
|
||||
if err == nil {
|
||||
msg := fmt.Sprintf("validation rule '%s' anyPattern[%d] passed.", v.rule.Name, idx)
|
||||
return ruleResponse(v.rule, msg, response.RuleStatusPass)
|
||||
}
|
||||
|
||||
v.log.V(3).Info("validation rule failed", "anyPattern[%d]", idx, "path", path)
|
||||
if path == "" {
|
||||
patternErr := fmt.Errorf("Rule %s[%d] failed: %s.", v.rule.Name, idx, err.Error())
|
||||
failedAnyPatternsErrors = append(failedAnyPatternsErrors, patternErr)
|
||||
} else {
|
||||
patternErr := fmt.Errorf("Rule %s[%d] failed at path %s.", v.rule.Name, idx, path)
|
||||
failedAnyPatternsErrors = append(failedAnyPatternsErrors, patternErr)
|
||||
if pe, ok := err.(*validate.PatternError); ok {
|
||||
v.log.V(3).Info("validation rule failed", "anyPattern[%d]", idx, "path", pe.Path)
|
||||
if pe.Path == "" {
|
||||
patternErr := fmt.Errorf("Rule %s[%d] failed: %s.", v.rule.Name, idx, err.Error())
|
||||
failedAnyPatternsErrors = append(failedAnyPatternsErrors, patternErr)
|
||||
} else {
|
||||
patternErr := fmt.Errorf("Rule %s[%d] failed at path %s.", v.rule.Name, idx, pe.Path)
|
||||
failedAnyPatternsErrors = append(failedAnyPatternsErrors, patternErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue