1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package collector
17
18 import (
19 "context"
20
21 "github.com/go-logr/logr"
22 v1 "k8s.io/api/core/v1"
23 apierrors "k8s.io/apimachinery/pkg/api/errors"
24 "k8s.io/apimachinery/pkg/runtime"
25 "k8s.io/apimachinery/pkg/types"
26 ctrl "sigs.k8s.io/controller-runtime"
27 "sigs.k8s.io/controller-runtime/pkg/client"
28 "sigs.k8s.io/controller-runtime/pkg/event"
29 "sigs.k8s.io/controller-runtime/pkg/predicate"
30
31 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
32 "github.com/chaos-mesh/chaos-mesh/pkg/dashboard/core"
33 )
34
35
36 type EventCollector struct {
37 client.Client
38 Log logr.Logger
39 apiType runtime.Object
40 event core.EventStore
41 }
42
43
44 func (r *EventCollector) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
45 if r.apiType == nil {
46 r.Log.Error(nil, "apiType has not been initialized")
47 return ctrl.Result{}, nil
48 }
49
50 event := &v1.Event{}
51 err := r.Get(ctx, req.NamespacedName, event)
52 if err != nil {
53 if !apierrors.IsNotFound(err) {
54 r.Log.Error(err, "unable to get event")
55 }
56 return ctrl.Result{}, nil
57 }
58 chaosKind, ok := v1alpha1.AllKinds()[event.InvolvedObject.Kind]
59 if ok {
60 chaosObject := chaosKind.SpawnObject()
61
62 if err = r.Get(ctx, types.NamespacedName{
63 Namespace: event.InvolvedObject.Namespace,
64 Name: event.InvolvedObject.Name,
65 }, chaosObject); err != nil {
66 return ctrl.Result{}, nil
67 }
68 } else if event.InvolvedObject.Kind == v1alpha1.KindSchedule {
69 if err = r.Get(ctx, types.NamespacedName{
70 Namespace: event.InvolvedObject.Namespace,
71 Name: event.InvolvedObject.Name,
72 }, &v1alpha1.Schedule{}); err != nil {
73 return ctrl.Result{}, nil
74 }
75 } else if event.InvolvedObject.Kind == v1alpha1.KindWorkflow {
76 if err = r.Get(ctx, types.NamespacedName{
77 Namespace: event.InvolvedObject.Namespace,
78 Name: event.InvolvedObject.Name,
79 }, &v1alpha1.Workflow{}); err != nil {
80 return ctrl.Result{}, nil
81 }
82 } else if event.InvolvedObject.Kind == v1alpha1.KindWorkflowNode {
83 if err = r.Get(ctx, types.NamespacedName{
84 Namespace: event.InvolvedObject.Namespace,
85 Name: event.InvolvedObject.Name,
86 }, &v1alpha1.WorkflowNode{}); err != nil {
87 return ctrl.Result{}, nil
88 }
89 } else {
90 r.Log.Info("event collector: omitted event", "involved object name", event.InvolvedObject.Name, "involved object namespace", event.InvolvedObject.Namespace, "involved object kind", event.InvolvedObject.Kind)
91 return ctrl.Result{}, nil
92 }
93
94 et := core.Event{
95 CreatedAt: event.CreationTimestamp.Time.UTC(),
96 Kind: event.InvolvedObject.Kind,
97 Type: event.Type,
98 Reason: event.Reason,
99 Message: event.Message,
100 Name: event.InvolvedObject.Name,
101 Namespace: event.InvolvedObject.Namespace,
102 ObjectID: string(event.InvolvedObject.UID),
103 }
104 if err := r.event.Create(context.Background(), &et); err != nil {
105 r.Log.Error(err, "failed to save event", "event", et)
106 }
107
108 return ctrl.Result{}, nil
109 }
110
111
112 func (r *EventCollector) Setup(mgr ctrl.Manager, apiType client.Object) error {
113 r.apiType = apiType
114
115 return ctrl.NewControllerManagedBy(mgr).
116 For(apiType).
117 WithEventFilter(predicate.Funcs{
118 CreateFunc: func(e event.CreateEvent) bool {
119 event, ok := e.Object.(*v1.Event)
120 if !ok {
121 return false
122 }
123 flag := false
124 _, ok = v1alpha1.AllKinds()[event.InvolvedObject.Kind]
125 if ok {
126 flag = true
127 }
128 if event.InvolvedObject.Kind == v1alpha1.KindSchedule {
129 flag = true
130 }
131 if event.InvolvedObject.Kind == v1alpha1.KindWorkflow {
132 flag = true
133 }
134 if event.InvolvedObject.Kind == v1alpha1.KindWorkflowNode {
135 flag = true
136 }
137 return flag
138
139 },
140 DeleteFunc: func(e event.DeleteEvent) bool {
141 return false
142 },
143 UpdateFunc: func(e event.UpdateEvent) bool {
144 return false
145 },
146 GenericFunc: func(e event.GenericEvent) bool {
147 return false
148 },
149 }).
150 Complete(r)
151 }
152