1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-31 03:45:17 +00:00

refactor: propagate exception in rule response (#6298)

* refactor: propagate exception in rule response

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

---------

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-02-10 21:14:34 +01:00 committed by GitHub
parent fe6e9abafa
commit f401071bb3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 13 additions and 30 deletions

View file

@ -1,8 +1,6 @@
package utils package utils
import ( import (
"strings"
"github.com/go-logr/logr" "github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/config"
engineapi "github.com/kyverno/kyverno/pkg/engine/api" engineapi "github.com/kyverno/kyverno/pkg/engine/api"
@ -36,7 +34,7 @@ func generateSuccessEvents(log logr.Logger, ers ...*engineapi.EngineResponse) (e
func generateExceptionEvents(log logr.Logger, ers ...*engineapi.EngineResponse) (eventInfos []event.Info) { func generateExceptionEvents(log logr.Logger, ers ...*engineapi.EngineResponse) (eventInfos []event.Info) {
for _, er := range ers { for _, er := range ers {
for i, ruleResp := range er.PolicyResponse.Rules { for i, ruleResp := range er.PolicyResponse.Rules {
isException := strings.Contains(ruleResp.Message, "rule skipped due to policy exception") isException := ruleResp.Exception != nil
if ruleResp.Status == engineapi.RuleStatusSkip && isException { if ruleResp.Status == engineapi.RuleStatusSkip && isException {
eventInfos = append(eventInfos, event.NewPolicyExceptionEvents(er, &er.PolicyResponse.Rules[i])...) eventInfos = append(eventInfos, event.NewPolicyExceptionEvents(er, &er.PolicyResponse.Rules[i])...)
} }

View file

@ -3,6 +3,7 @@ package api
import ( import (
"fmt" "fmt"
kyvernov2alpha1 "github.com/kyverno/kyverno/api/kyverno/v2alpha1"
pssutils "github.com/kyverno/kyverno/pkg/pss/utils" pssutils "github.com/kyverno/kyverno/pkg/pss/utils"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@ -43,6 +44,8 @@ type RuleResponse struct {
PatchedTargetParentResourceGVR metav1.GroupVersionResource PatchedTargetParentResourceGVR metav1.GroupVersionResource
// PodSecurityChecks contains pod security checks (only if this is a pod security rule) // PodSecurityChecks contains pod security checks (only if this is a pod security rule)
PodSecurityChecks *PodSecurityChecks PodSecurityChecks *PodSecurityChecks
// Exception is the exception applied (if any)
Exception *kyvernov2alpha1.PolicyException
} }
// HasStatus checks if rule status is in a given list // HasStatus checks if rule status is in a given list

View file

@ -83,19 +83,18 @@ func hasPolicyExceptions(
) *engineapi.RuleResponse { ) *engineapi.RuleResponse {
// if matches, check if there is a corresponding policy exception // if matches, check if there is a corresponding policy exception
exception, err := matchesException(selector, ctx, rule, subresourceGVKToAPIResource, cfg) exception, err := matchesException(selector, ctx, rule, subresourceGVKToAPIResource, cfg)
var response *engineapi.RuleResponse
// if we found an exception // if we found an exception
if err == nil && exception != nil { if err == nil && exception != nil {
key, err := cache.MetaNamespaceKeyFunc(exception) key, err := cache.MetaNamespaceKeyFunc(exception)
if err != nil { if err != nil {
log.Error(err, "failed to compute policy exception key", "namespace", exception.GetNamespace(), "name", exception.GetName()) log.Error(err, "failed to compute policy exception key", "namespace", exception.GetNamespace(), "name", exception.GetName())
return &engineapi.RuleResponse{ response = internal.RuleError(rule, ruleType, "failed to compute exception key", err)
Name: rule.Name, } else {
Message: "failed to find matched exception " + key,
Status: engineapi.RuleStatusError,
}
}
log.V(3).Info("policy rule skipped due to policy exception", "exception", key) log.V(3).Info("policy rule skipped due to policy exception", "exception", key)
return internal.RuleSkip(rule, ruleType, "rule skipped due to policy exception "+key) response = internal.RuleSkip(rule, ruleType, "rule skipped due to policy exception "+key)
response.Exception = exception
} }
return nil }
return response
} }

View file

@ -124,7 +124,7 @@ func NewBackgroundSuccessEvent(policy, rule string, source Source, r *unstructur
} }
func NewPolicyExceptionEvents(engineResponse *engineapi.EngineResponse, ruleResp *engineapi.RuleResponse) []Info { func NewPolicyExceptionEvents(engineResponse *engineapi.EngineResponse, ruleResp *engineapi.RuleResponse) []Info {
exceptionName, exceptionNamespace := getExceptionEventInfoFromRuleResponseMsg(ruleResp.Message) exceptionName, exceptionNamespace := ruleResp.Exception.GetName(), ruleResp.Exception.GetNamespace()
policyMessage := fmt.Sprintf("resource %s was skipped from rule %s due to policy exception %s/%s", engineResponse.PatchedResource.GetName(), ruleResp.Name, exceptionNamespace, exceptionName) policyMessage := fmt.Sprintf("resource %s was skipped from rule %s due to policy exception %s/%s", engineResponse.PatchedResource.GetName(), ruleResp.Name, exceptionNamespace, exceptionName)
var exceptionMessage string var exceptionMessage string
if engineResponse.Policy.GetNamespace() == "" { if engineResponse.Policy.GetNamespace() == "" {
@ -148,18 +148,3 @@ func NewPolicyExceptionEvents(engineResponse *engineapi.EngineResponse, ruleResp
} }
return []Info{policyEvent, exceptionEvent} return []Info{policyEvent, exceptionEvent}
} }
func getExceptionEventInfoFromRuleResponseMsg(message string) (name string, namespace string) {
key := message[strings.LastIndex(message, " ")+1:]
arr := strings.Split(key, "/")
if len(arr) > 1 {
namespace = arr[0]
name = arr[1]
} else {
namespace = ""
name = arr[0]
}
return name, namespace
}

View file

@ -1,8 +1,6 @@
package utils package utils
import ( import (
"strings"
engineapi "github.com/kyverno/kyverno/pkg/engine/api" engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/event" "github.com/kyverno/kyverno/pkg/event"
) )
@ -34,7 +32,7 @@ func GenerateEvents(engineResponses []*engineapi.EngineResponse, blocked bool) [
} }
} else if er.IsSkipped() { // Handle PolicyException Event } else if er.IsSkipped() { // Handle PolicyException Event
for i, ruleResp := range er.PolicyResponse.Rules { for i, ruleResp := range er.PolicyResponse.Rules {
isException := strings.Contains(ruleResp.Message, "rule skipped due to policy exception") isException := ruleResp.Exception != nil
if ruleResp.Status == engineapi.RuleStatusSkip && !blocked && isException { if ruleResp.Status == engineapi.RuleStatusSkip && !blocked && isException {
events = append(events, event.NewPolicyExceptionEvents(er, &er.PolicyResponse.Rules[i])...) events = append(events, event.NewPolicyExceptionEvents(er, &er.PolicyResponse.Rules[i])...)
} }