1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

fix: generate policy exception events (#5987)

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-01-13 10:18:14 +01:00 committed by GitHub
parent 45fe02a989
commit 330709a7b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 18 deletions

View file

@ -1,6 +1,8 @@
package utils
import (
"strings"
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine/response"
@ -9,7 +11,9 @@ import (
func GenerateEvents(logger logr.Logger, eventGen event.Interface, config config.Configuration, results ...*response.EngineResponse) {
for _, result := range results {
eventInfos := generateFailEvents(logger, result)
var eventInfos []event.Info
eventInfos = append(eventInfos, generateFailEvents(logger, result)...)
eventInfos = append(eventInfos, generateExceptionEvents(logger, result)...)
if config.GetGenerateSuccessEvents() {
eventInfos = append(eventInfos, generateSuccessEvents(logger, result)...)
}
@ -29,6 +33,18 @@ func generateSuccessEvents(log logr.Logger, ers ...*response.EngineResponse) (ev
return eventInfos
}
func generateExceptionEvents(log logr.Logger, ers ...*response.EngineResponse) (eventInfos []event.Info) {
for _, er := range ers {
for i, ruleResp := range er.PolicyResponse.Rules {
isException := strings.Contains(ruleResp.Message, "rule skipped due to policy exception")
if ruleResp.Status == response.RuleStatusSkip && isException {
eventInfos = append(eventInfos, event.NewPolicyExceptionEvents(er, &er.PolicyResponse.Rules[i])...)
}
}
}
return eventInfos
}
func generateFailEvents(log logr.Logger, ers ...*response.EngineResponse) (eventInfos []event.Info) {
for _, er := range ers {
eventInfos = append(eventInfos, generateFailEventsPerEr(log, er)...)

View file

@ -46,7 +46,6 @@ func getPolicyKind(policy kyvernov1.PolicyInterface) string {
if policy.IsNamespaced() {
return "Policy"
}
return "ClusterPolicy"
}
@ -126,21 +125,30 @@ func NewBackgroundSuccessEvent(policy, rule string, source Source, r *unstructur
return events
}
func NewPolicyExceptionEvent(engineResponse *response.EngineResponse, ruleResp *response.RuleResponse) Info {
var messageBuilder strings.Builder
defer messageBuilder.Reset()
func NewPolicyExceptionEvents(engineResponse *response.EngineResponse, ruleResp *response.RuleResponse) []Info {
exceptionName, exceptionNamespace := getExceptionEventInfoFromRuleResponseMsg(ruleResp.Message)
fmt.Fprintf(&messageBuilder, "resource %s was skipped from rule %s due to policy exception %s/%s", engineResponse.PatchedResource.GetName(), ruleResp.Name, exceptionNamespace, exceptionName)
return Info{
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
if engineResponse.PolicyResponse.Policy.Namespace == "" {
exceptionMessage = fmt.Sprintf("resource %s was skipped from policy rule %s/%s", engineResponse.PatchedResource.GetName(), engineResponse.PolicyResponse.Policy.Name, ruleResp.Name)
} else {
exceptionMessage = fmt.Sprintf("resource %s was skipped from policy rule %s/%s/%s", engineResponse.PatchedResource.GetName(), engineResponse.PolicyResponse.Policy.Namespace, engineResponse.PolicyResponse.Policy.Name, ruleResp.Name)
}
policyEvent := Info{
Kind: getPolicyKind(engineResponse.Policy),
Name: engineResponse.PolicyResponse.Policy.Name,
Namespace: engineResponse.PolicyResponse.Policy.Namespace,
Reason: PolicySkipped.String(),
Message: messageBuilder.String(),
Message: policyMessage,
}
exceptionEvent := Info{
Kind: "PolicyException",
Name: exceptionName,
Namespace: exceptionNamespace,
Reason: PolicySkipped.String(),
Message: exceptionMessage,
}
return []Info{policyEvent, exceptionEvent}
}
func getExceptionEventInfoFromRuleResponseMsg(message string) (name string, namespace string) {

View file

@ -10,7 +10,6 @@ import (
// GenerateEvents generates event info for the engine responses
func GenerateEvents(engineResponses []*response.EngineResponse, blocked bool) []event.Info {
var events []event.Info
// - Some/All policies fail or error
// - report failure events on policy
// - report failure events on resource
@ -18,19 +17,16 @@ func GenerateEvents(engineResponses []*response.EngineResponse, blocked bool) []
// - report success event on resource
// - Some/All policies skipped
// - report skipped event on resource
for _, er := range engineResponses {
if er.IsEmpty() {
continue
}
if !er.IsSuccessful() {
for i, ruleResp := range er.PolicyResponse.Rules {
if ruleResp.Status == response.RuleStatusFail || ruleResp.Status == response.RuleStatusError {
e := event.NewPolicyFailEvent(event.AdmissionController, event.PolicyViolation, er, &er.PolicyResponse.Rules[i], blocked)
events = append(events, e)
}
if !blocked {
e := event.NewResourceViolationEvent(event.AdmissionController, event.PolicyViolation, er, &er.PolicyResponse.Rules[i])
events = append(events, e)
@ -40,8 +36,7 @@ func GenerateEvents(engineResponses []*response.EngineResponse, blocked bool) []
for i, ruleResp := range er.PolicyResponse.Rules {
isException := strings.Contains(ruleResp.Message, "rule skipped due to policy exception")
if ruleResp.Status == response.RuleStatusSkip && !blocked && isException {
e := event.NewPolicyExceptionEvent(er, &er.PolicyResponse.Rules[i])
events = append(events, e)
events = append(events, event.NewPolicyExceptionEvents(er, &er.PolicyResponse.Rules[i])...)
}
}
} else if !er.IsSkipped() {
@ -49,6 +44,5 @@ func GenerateEvents(engineResponses []*response.EngineResponse, blocked bool) []
events = append(events, e)
}
}
return events
}