1 package reconcile
2
3 import (
4 "context"
5
6 corev1 "k8s.io/api/core/v1"
7 "k8s.io/client-go/tools/record"
8 ctrl "sigs.k8s.io/controller-runtime"
9 "sigs.k8s.io/controller-runtime/pkg/client"
10
11 "edge-infra.dev/pkg/k8s/meta/status"
12 "edge-infra.dev/pkg/k8s/runtime/conditions"
13 "edge-infra.dev/pkg/k8s/runtime/controller/reconcile/recerr"
14 )
15
16
17
18
19 type ResultProcessor func(context.Context, record.EventRecorder, conditions.Setter, Result, error)
20
21
22
23
24 func RecordReconcileReq(_ context.Context, _ record.EventRecorder, obj conditions.Setter, _ Result, _ error) {
25 if v, ok := GetAnnotation(obj.GetAnnotations()); ok {
26 _ = SetStatusLastHandledReconcileAt(obj, v)
27 }
28 }
29
30
31
32 func RecordResult(ctx context.Context, recorder record.EventRecorder, obj conditions.Setter, _ Result, err error) {
33 reason := conditions.GetReason(obj, status.ReadyCondition)
34 switch e := err.(type) {
35 case *recerr.Generic:
36 logError(ctx, e.Event, e, e.Error())
37 recordEvent(recorder, obj, e.Event, e.Notification, err.Error(), e.Reason)
38 case *recerr.Wait:
39 logError(ctx, e.Event, e, "reconciliation waiting",
40 "reason", e.Err,
41 "duration", e.Config.RequeueAfter,
42 )
43 recordEvent(recorder, obj, e.Event, e.Notification, err.Error(), e.Reason)
44 case *recerr.Stalled:
45 logError(ctx, e.Event, e, "reconciliation stalled")
46 recordEvent(recorder, obj, e.Event, e.Notification, err.Error(), e.Reason)
47 case error:
48 logError(ctx, corev1.EventTypeWarning, e, e.Error())
49 if reason == "" {
50 reason = "ReconcileFailed"
51 }
52 recordEvent(recorder, obj, corev1.EventTypeWarning, true, err.Error(), reason)
53 case nil:
54 if !conditions.IsReady(obj) {
55 return
56 }
57
58
59 message := conditions.GetMessage(obj, status.ReadyCondition)
60 recordEvent(recorder, obj, corev1.EventTypeNormal, true, message, reason)
61 }
62 }
63
64
65 func logError(ctx context.Context, eventType string, err error, msg string, keysAndValues ...interface{}) {
66 log := ctrl.LoggerFrom(ctx)
67 switch eventType {
68 case corev1.EventTypeNormal, recerr.EventTypeNone:
69 log.Info(msg, keysAndValues...)
70 case corev1.EventTypeWarning:
71 log.Error(err, msg, keysAndValues...)
72 }
73 }
74
75
76 func recordEvent(recorder record.EventRecorder, obj client.Object, eventType string, notification bool, message, reason string) {
77 if recorder == nil || eventType == recerr.EventTypeNone {
78 return
79 }
80 switch eventType {
81 case corev1.EventTypeNormal:
82 if notification {
83 recorder.Eventf(obj, corev1.EventTypeNormal, reason, message)
84 }
85 return
86 case corev1.EventTypeWarning:
87 recorder.Eventf(obj, corev1.EventTypeWarning, reason, message)
88 return
89 }
90 }
91
View as plain text