2022-05-01 22:14:32 -07:00
package event
import (
"fmt"
"strings"
2022-05-17 13:12:43 +02:00
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
2023-01-30 12:41:09 +01:00
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
2022-05-01 22:14:32 -07:00
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
2023-01-30 12:41:09 +01:00
func NewPolicyFailEvent ( source Source , reason Reason , engineResponse * engineapi . EngineResponse , ruleResp * engineapi . RuleResponse , blocked bool ) Info {
2022-06-22 09:37:46 -07:00
return Info {
2022-05-01 22:14:32 -07:00
Kind : getPolicyKind ( engineResponse . Policy ) ,
Name : engineResponse . PolicyResponse . Policy . Name ,
Namespace : engineResponse . PolicyResponse . Policy . Namespace ,
2023-01-26 22:19:02 +01:00
Reason : reason ,
2022-05-01 22:14:32 -07:00
Source : source ,
2023-01-26 22:19:02 +01:00
Message : buildPolicyEventMessage ( ruleResp , engineResponse . GetResourceSpec ( ) , blocked ) ,
2022-05-01 22:14:32 -07:00
}
}
2023-01-30 12:41:09 +01:00
func buildPolicyEventMessage ( resp * engineapi . RuleResponse , resource engineapi . ResourceSpec , blocked bool ) string {
2022-05-01 22:14:32 -07:00
var b strings . Builder
if resource . Namespace != "" {
fmt . Fprintf ( & b , "%s %s/%s" , resource . Kind , resource . Namespace , resource . Name )
} else {
fmt . Fprintf ( & b , "%s %s" , resource . Kind , resource . Name )
}
2023-01-30 12:41:09 +01:00
fmt . Fprintf ( & b , ": [%s] %s" , resp . Name , resp . Status )
2022-05-01 22:14:32 -07:00
if blocked {
fmt . Fprintf ( & b , " (blocked)" )
}
2023-01-30 12:41:09 +01:00
if resp . Status == engineapi . RuleStatusError && resp . Message != "" {
2022-08-09 10:23:50 +05:30
fmt . Fprintf ( & b , "; %s" , resp . Message )
2022-05-01 22:14:32 -07:00
}
return b . String ( )
}
2022-05-17 13:12:43 +02:00
func getPolicyKind ( policy kyvernov1 . PolicyInterface ) string {
2022-05-01 22:14:32 -07:00
if policy . IsNamespaced ( ) {
return "Policy"
}
return "ClusterPolicy"
}
2023-01-30 12:41:09 +01:00
func NewPolicyAppliedEvent ( source Source , engineResponse * engineapi . EngineResponse ) Info {
2022-05-01 22:14:32 -07:00
resource := engineResponse . PolicyResponse . Resource
2022-06-22 09:37:46 -07:00
var bldr strings . Builder
defer bldr . Reset ( )
2022-05-01 22:14:32 -07:00
if resource . Namespace != "" {
2022-06-22 09:37:46 -07:00
fmt . Fprintf ( & bldr , "%s %s/%s: pass" , resource . Kind , resource . Namespace , resource . Name )
2022-05-01 22:14:32 -07:00
} else {
2022-06-22 09:37:46 -07:00
fmt . Fprintf ( & bldr , "%s %s: pass" , resource . Kind , resource . Name )
2022-05-01 22:14:32 -07:00
}
2022-06-22 09:37:46 -07:00
return Info {
2022-05-01 22:14:32 -07:00
Kind : getPolicyKind ( engineResponse . Policy ) ,
Name : engineResponse . PolicyResponse . Policy . Name ,
Namespace : engineResponse . PolicyResponse . Policy . Namespace ,
2023-01-26 22:19:02 +01:00
Reason : PolicyApplied ,
2022-05-01 22:14:32 -07:00
Source : source ,
2022-06-22 09:37:46 -07:00
Message : bldr . String ( ) ,
2022-05-01 22:14:32 -07:00
}
}
2023-01-30 12:41:09 +01:00
func NewResourceViolationEvent ( source Source , reason Reason , engineResponse * engineapi . EngineResponse , ruleResp * engineapi . RuleResponse ) Info {
2022-06-22 09:37:46 -07:00
var bldr strings . Builder
defer bldr . Reset ( )
fmt . Fprintf ( & bldr , "policy %s/%s %s: %s" , engineResponse . Policy . GetName ( ) ,
2023-01-30 12:41:09 +01:00
ruleResp . Name , ruleResp . Status , ruleResp . Message )
2022-05-01 22:14:32 -07:00
resource := engineResponse . GetResourceSpec ( )
2022-06-22 09:37:46 -07:00
return Info {
2022-05-01 22:14:32 -07:00
Kind : resource . Kind ,
Name : resource . Name ,
Namespace : resource . Namespace ,
2023-01-26 22:19:02 +01:00
Reason : reason ,
2022-05-01 22:14:32 -07:00
Source : source ,
2022-06-22 09:37:46 -07:00
Message : bldr . String ( ) ,
2022-05-01 22:14:32 -07:00
}
}
func NewBackgroundFailedEvent ( err error , policy , rule string , source Source , r * unstructured . Unstructured ) [ ] Info {
if r == nil {
return nil
}
var events [ ] Info
events = append ( events , Info {
Kind : r . GetKind ( ) ,
Namespace : r . GetNamespace ( ) ,
Name : r . GetName ( ) ,
Source : source ,
2023-01-26 22:19:02 +01:00
Reason : PolicyError ,
2022-05-01 22:14:32 -07:00
Message : fmt . Sprintf ( "policy %s/%s error: %v" , policy , rule , err ) ,
} )
return events
}
func NewBackgroundSuccessEvent ( policy , rule string , source Source , r * unstructured . Unstructured ) [ ] Info {
if r == nil {
return nil
}
var events [ ] Info
msg := fmt . Sprintf ( "policy %s/%s applied" , policy , rule )
events = append ( events , Info {
Kind : r . GetKind ( ) ,
Namespace : r . GetNamespace ( ) ,
Name : r . GetName ( ) ,
Source : source ,
2023-01-26 22:19:02 +01:00
Reason : PolicyApplied ,
2022-05-01 22:14:32 -07:00
Message : msg ,
} )
return events
}
2022-12-22 18:34:09 -05:00
2023-01-30 12:41:09 +01:00
func NewPolicyExceptionEvents ( engineResponse * engineapi . EngineResponse , ruleResp * engineapi . RuleResponse ) [ ] Info {
2022-12-22 18:34:09 -05:00
exceptionName , exceptionNamespace := getExceptionEventInfoFromRuleResponseMsg ( ruleResp . Message )
2023-01-13 10:18:14 +01:00
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 {
2022-12-22 18:34:09 -05:00
Kind : getPolicyKind ( engineResponse . Policy ) ,
Name : engineResponse . PolicyResponse . Policy . Name ,
Namespace : engineResponse . PolicyResponse . Policy . Namespace ,
2023-01-26 22:19:02 +01:00
Reason : PolicySkipped ,
2023-01-13 10:18:14 +01:00
Message : policyMessage ,
}
exceptionEvent := Info {
Kind : "PolicyException" ,
Name : exceptionName ,
Namespace : exceptionNamespace ,
2023-01-26 22:19:02 +01:00
Reason : PolicySkipped ,
2023-01-13 10:18:14 +01:00
Message : exceptionMessage ,
2022-12-22 18:34:09 -05:00
}
2023-01-13 10:18:14 +01:00
return [ ] Info { policyEvent , exceptionEvent }
2022-12-22 18:34:09 -05:00
}
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
}