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:
parent
fe6e9abafa
commit
f401071bb3
5 changed files with 13 additions and 30 deletions
|
@ -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])...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
|
@ -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])...)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue