-
Notifications
You must be signed in to change notification settings - Fork 106
/
events.go
110 lines (94 loc) · 3.33 KB
/
events.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package common
import (
"fmt"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/record"
"sigs.k8s.io/controller-runtime/pkg/manager"
compv1alpha1 "github.com/openshift/compliance-operator/pkg/apis/compliance/v1alpha1"
)
type SafeRecorder struct {
recorder record.EventRecorder
}
func NewSafeRecorder(name string, mgr manager.Manager) *SafeRecorder {
return &SafeRecorder{recorder: mgr.GetEventRecorderFor(name)}
}
func (sr *SafeRecorder) Event(object runtime.Object, eventtype, reason, message string) {
if sr.recorder == nil {
return
}
sr.recorder.Event(object, eventtype, reason, message)
}
// Eventf is just like Event, but with Sprintf for the message field.
func (sr *SafeRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) {
if sr.recorder == nil {
return
}
sr.recorder.Eventf(object, eventtype, reason, messageFmt, args...)
}
// AnnotatedEventf is just like eventf, but with annotations attached
func (sr *SafeRecorder) AnnotatedEventf(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) {
if sr.recorder == nil {
return
}
sr.recorder.AnnotatedEventf(object, annotations, eventtype, reason, messageFmt, args...)
}
func GenerateEventForResult(recorder record.EventRecorder, obj runtime.Object, objInfo metav1.Object, result compv1alpha1.ComplianceScanStatusResult) {
// Event for Suite
recorder.Event(
obj,
corev1.EventTypeNormal,
"ResultAvailable",
fmt.Sprintf("The result is: %s", result),
)
ownerRefs := objInfo.GetOwnerReferences()
if len(ownerRefs) == 0 {
return //there is nothing to do, since no owner is set
}
for idx := range ownerRefs {
ownerRef := &ownerRefs[idx]
// we are making an assumption that the GRC policy has a single owner, or we chose the first owner in the list
if string(ownerRef.UID) == "" {
continue //there is nothing to do, since no owner UID is set
}
// FIXME(jaosorior): Figure out a less hacky way to check this
if ownerRef.Kind == "Policy" {
pol := getParentPolicy(ownerRef, objInfo.GetNamespace())
recorder.Event(
pol,
corev1.EventTypeNormal,
fmt.Sprintf("policy: %s/%s", objInfo.GetNamespace(), objInfo.GetName()),
resultToACMPolicyStatus(objInfo.GetNamespace(), objInfo.GetName(), result),
)
}
}
}
func getParentPolicy(ownerRef *metav1.OwnerReference, ns string) *unstructured.Unstructured {
return &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": ownerRef.APIVersion,
"kind": ownerRef.Kind,
"metadata": map[string]interface{}{
"name": ownerRef.Name,
"namespace": ns,
"uid": ownerRef.UID,
},
},
}
}
func resultToACMPolicyStatus(namespace, name string, scanresult compv1alpha1.ComplianceScanStatusResult) string {
const instfmt string = "; To view aggregated results, execute the following in the managed cluster: kubectl get compliancesuites -n %s %s"
instructions := fmt.Sprintf(instfmt, namespace, name)
var result string
switch scanresult {
case compv1alpha1.ResultCompliant:
result = "Compliant"
case compv1alpha1.ResultNonCompliant:
result = "NonCompliant"
default:
result = "UnknownCompliancy"
}
return result + instructions
}