Skip to content

Commit 2dd21e4

Browse files
committed
Update events/v1 and use Flux runtime event recorder and populate source reference
Replace the local eventLogf helper with direct calls to the fluxcd/pkg/runtime/events.EventRecorder interface. This removes redundant logging (the recorder handles it internally) and aligns with the pattern used by other Flux controllers. Populate the GitRepository as the related object in all emitted events, enabling notification-controller and other consumers to correlate automation events with their source. Signed-off-by: Adrian Fernandez De La Torre <adri1197@gmail.com>
1 parent 556f03a commit 2dd21e4

4 files changed

Lines changed: 44 additions & 35 deletions

File tree

internal/controller/imageupdateautomation_controller.go

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ import (
2626
apierrors "k8s.io/apimachinery/pkg/api/errors"
2727
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2828
"k8s.io/apimachinery/pkg/labels"
29-
"k8s.io/apimachinery/pkg/runtime"
3029
kerrors "k8s.io/apimachinery/pkg/util/errors"
31-
kuberecorder "k8s.io/client-go/tools/record"
3230
"k8s.io/client-go/util/workqueue"
3331
ctrl "sigs.k8s.io/controller-runtime"
3432
"sigs.k8s.io/controller-runtime/pkg/builder"
@@ -41,14 +39,15 @@ import (
4139

4240
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1"
4341
aclapi "github.com/fluxcd/pkg/apis/acl"
44-
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
42+
eventv1 "github.com/fluxcd/pkg/apis/event/v1"
4543
"github.com/fluxcd/pkg/apis/meta"
4644
"github.com/fluxcd/pkg/auth"
4745
"github.com/fluxcd/pkg/cache"
4846
"github.com/fluxcd/pkg/git"
4947
"github.com/fluxcd/pkg/runtime/acl"
5048
"github.com/fluxcd/pkg/runtime/conditions"
5149
helper "github.com/fluxcd/pkg/runtime/controller"
50+
"github.com/fluxcd/pkg/runtime/events"
5251
"github.com/fluxcd/pkg/runtime/patch"
5352
"github.com/fluxcd/pkg/runtime/predicates"
5453
runtimereconcile "github.com/fluxcd/pkg/runtime/reconcile"
@@ -102,7 +101,7 @@ func getPatchOptions(ownedConditions []string, controllerName string) []patch.Op
102101
// ImageUpdateAutomationReconciler reconciles a ImageUpdateAutomation object
103102
type ImageUpdateAutomationReconciler struct {
104103
client.Client
105-
kuberecorder.EventRecorder
104+
events.EventRecorder
106105
helper.Metrics
107106

108107
ControllerName string
@@ -608,6 +607,7 @@ func observedPoliciesChanged(previous, current imagev1.ObservedPolicies) bool {
608607
// case of any failure, the failure message is read from the Ready condition and
609608
// included in the event.
610609
func (r *ImageUpdateAutomationReconciler) notify(ctx context.Context, oldObj, newObj conditions.Setter, result *source.PushResult, syncNeeded bool) {
610+
related := sourceRefObject(newObj)
611611
// Use the Ready message as the notification message by default.
612612
ready := conditions.Get(newObj, meta.ReadyCondition)
613613
msg := ready.Message
@@ -619,20 +619,20 @@ func (r *ImageUpdateAutomationReconciler) notify(ctx context.Context, oldObj, ne
619619

620620
// Was ready before and is ready now, with new push result,
621621
if conditions.IsReady(oldObj) && conditions.IsReady(newObj) && result != nil {
622-
eventLogf(ctx, r.EventRecorder, newObj, corev1.EventTypeNormal, ready.Reason, "%s", msg)
622+
r.Eventf(newObj, related, corev1.EventTypeNormal, ready.Reason, "", "%s", msg)
623623
return
624624
}
625625

626626
// Emit events when reconciliation fails or recovers from failure.
627627

628628
// Became ready from not ready.
629629
if !conditions.IsReady(oldObj) && conditions.IsReady(newObj) {
630-
eventLogf(ctx, r.EventRecorder, newObj, corev1.EventTypeNormal, ready.Reason, "%s", msg)
630+
r.Eventf(newObj, related, corev1.EventTypeNormal, ready.Reason, "", "%s", msg)
631631
return
632632
}
633633
// Not ready, failed. Use the failure message from ready condition.
634634
if !conditions.IsReady(newObj) {
635-
eventLogf(ctx, r.EventRecorder, newObj, corev1.EventTypeWarning, ready.Reason, "%s", ready.Message)
635+
r.Eventf(newObj, related, corev1.EventTypeWarning, ready.Reason, "", "%s", ready.Message)
636636
return
637637
}
638638

@@ -642,21 +642,30 @@ func (r *ImageUpdateAutomationReconciler) notify(ctx context.Context, oldObj, ne
642642
// Full reconciliation skipped.
643643
msg = "no change since last reconciliation"
644644
}
645-
eventLogf(ctx, r.EventRecorder, newObj, eventv1.EventTypeTrace, meta.SucceededReason, "%s", msg)
645+
r.Eventf(newObj, related, eventv1.EventTypeTrace, meta.SucceededReason, "", "%s", msg)
646646
}
647647

648-
// eventLogf records events, and logs at the same time.
649-
//
650-
// This log is different from the debug log in the EventRecorder, in the sense
651-
// that this is a simple log. While the debug log contains complete details
652-
// about the event.
653-
func eventLogf(ctx context.Context, r kuberecorder.EventRecorder, obj runtime.Object, eventType string, reason string, messageFmt string, args ...interface{}) {
654-
msg := fmt.Sprintf(messageFmt, args...)
655-
// Log and emit event.
656-
if eventType == corev1.EventTypeWarning {
657-
ctrl.LoggerFrom(ctx).Error(errors.New(reason), msg)
658-
} else {
659-
ctrl.LoggerFrom(ctx).Info(msg)
648+
// sourceRefObject returns a minimal GitRepository object for use as the
649+
// related object in events. It extracts the source reference from the
650+
// ImageUpdateAutomation spec.
651+
func sourceRefObject(obj conditions.Setter) *sourcev1.GitRepository {
652+
auto, ok := obj.(*imagev1.ImageUpdateAutomation)
653+
if !ok {
654+
return nil
655+
}
656+
ref := auto.Spec.SourceRef
657+
ns := ref.Namespace
658+
if ns == "" {
659+
ns = auto.Namespace
660+
}
661+
return &sourcev1.GitRepository{
662+
TypeMeta: metav1.TypeMeta{
663+
Kind: sourcev1.GitRepositoryKind,
664+
APIVersion: sourcev1.GroupVersion.String(),
665+
},
666+
ObjectMeta: metav1.ObjectMeta{
667+
Name: ref.Name,
668+
Namespace: ns,
669+
},
660670
}
661-
r.Eventf(obj, eventType, reason, msg)
662671
}

internal/controller/imageupdateautomation_controller_test.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import (
3939
"k8s.io/apimachinery/pkg/types"
4040
"k8s.io/apimachinery/pkg/util/rand"
4141
"k8s.io/apimachinery/pkg/util/validation"
42-
"k8s.io/client-go/tools/record"
4342
ctrl "sigs.k8s.io/controller-runtime"
4443
"sigs.k8s.io/controller-runtime/pkg/client"
4544
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
@@ -51,6 +50,7 @@ import (
5150
"github.com/fluxcd/pkg/gittestserver"
5251
"github.com/fluxcd/pkg/runtime/conditions"
5352
conditionscheck "github.com/fluxcd/pkg/runtime/conditions/check"
53+
"github.com/fluxcd/pkg/runtime/events"
5454
"github.com/fluxcd/pkg/runtime/patch"
5555
"github.com/fluxcd/pkg/ssh"
5656
sourcev1 "github.com/fluxcd/source-controller/api/v1"
@@ -128,7 +128,7 @@ func TestImageUpdateAutomationReconciler_deleteBeforeFinalizer(t *testing.T) {
128128

129129
r := &ImageUpdateAutomationReconciler{
130130
Client: k8sClient,
131-
EventRecorder: record.NewFakeRecorder(32),
131+
EventRecorder: events.NewFakeRecorder(32, false),
132132
}
133133
// NOTE: Only a real API server responds with an error in this scenario.
134134
g.Eventually(func() error {
@@ -1057,7 +1057,7 @@ func TestImageUpdateAutomationReconciler_crossNamespaceRef(t *testing.T) {
10571057
WithScheme(testEnv.Scheme()).
10581058
WithStatusSubresource(&imagev1.ImageUpdateAutomation{}, &reflectorv1.ImagePolicy{}).
10591059
Build(),
1060-
EventRecorder: testEnv.GetEventRecorderFor("image-automation-controller"),
1060+
EventRecorder: events.NewNopRecorder(),
10611061
NoCrossNamespaceRef: true,
10621062
}
10631063

@@ -1629,7 +1629,7 @@ func TestImageUpdateAutomationReconciler_notify(t *testing.T) {
16291629
for _, tt := range tests {
16301630
t.Run(tt.name, func(t *testing.T) {
16311631
g := NewWithT(t)
1632-
recorder := record.NewFakeRecorder(32)
1632+
recorder := events.NewFakeRecorder(32, false)
16331633

16341634
oldObj := &imagev1.ImageUpdateAutomation{}
16351635
newObj := oldObj.DeepCopy()
@@ -1647,10 +1647,11 @@ func TestImageUpdateAutomationReconciler_notify(t *testing.T) {
16471647
reconciler.notify(ctx, oldObj, newObj, tt.pushResult, tt.syncNeeded)
16481648

16491649
select {
1650-
case x, ok := <-recorder.Events:
1650+
case ev, ok := <-recorder.Events:
16511651
g.Expect(ok).To(Equal(tt.wantEvent != ""), "unexpected event received")
16521652
if tt.wantEvent != "" {
1653-
g.Expect(x).To(ContainSubstring(tt.wantEvent))
1653+
got := fmt.Sprintf("%s %s %s", ev.Type, ev.Reason, ev.Note)
1654+
g.Expect(got).To(ContainSubstring(tt.wantEvent))
16541655
}
16551656
default:
16561657
if tt.wantEvent != "" {

internal/controller/suite_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ import (
2626

2727
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
2828
"k8s.io/client-go/kubernetes/scheme"
29-
"k8s.io/client-go/tools/record"
3029
ctrl "sigs.k8s.io/controller-runtime"
3130
"sigs.k8s.io/controller-runtime/pkg/client"
3231

3332
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1"
3433
"github.com/fluxcd/pkg/runtime/controller"
34+
"github.com/fluxcd/pkg/runtime/events"
3535
"github.com/fluxcd/pkg/runtime/testenv"
3636
sourcev1 "github.com/fluxcd/source-controller/api/v1"
3737

@@ -87,7 +87,7 @@ func runTestsWithFeatures(m *testing.M, feats map[string]bool) int {
8787
controllerName := "image-automation-controller"
8888
if err := (&ImageUpdateAutomationReconciler{
8989
Client: testEnv,
90-
EventRecorder: record.NewFakeRecorder(32),
90+
EventRecorder: events.NewNopRecorder(),
9191
features: feats,
9292
ControllerName: controllerName,
9393
}).SetupWithManager(ctx, testEnv, ImageUpdateAutomationReconcilerOptions{

main.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
2727
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
2828
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
29-
"k8s.io/utils/pointer"
29+
"k8s.io/utils/ptr"
3030
ctrl "sigs.k8s.io/controller-runtime"
3131
ctrlcache "sigs.k8s.io/controller-runtime/pkg/cache"
3232
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
@@ -49,10 +49,9 @@ import (
4949
"github.com/fluxcd/pkg/runtime/probes"
5050
sourcev1 "github.com/fluxcd/source-controller/api/v1"
5151

52-
"github.com/fluxcd/pkg/git"
53-
5452
imagev1 "github.com/fluxcd/image-automation-controller/api/v1"
5553
"github.com/fluxcd/image-automation-controller/internal/features"
54+
"github.com/fluxcd/pkg/git"
5655

5756
// +kubebuilder:scaffold:imports
5857
"github.com/fluxcd/image-automation-controller/internal/controller"
@@ -196,7 +195,7 @@ func main() {
196195
ExtraHandlers: pprof.GetHandlers(),
197196
},
198197
Controller: ctrlcfg.Controller{
199-
RecoverPanic: pointer.Bool(true),
198+
RecoverPanic: ptr.To(true),
200199
MaxConcurrentReconciles: concurrent,
201200
},
202201
}
@@ -215,8 +214,8 @@ func main() {
215214

216215
probes.SetupChecks(mgr, setupLog)
217216

218-
var eventRecorder *events.Recorder
219-
if eventRecorder, err = events.NewRecorder(mgr, ctrl.Log, eventsAddr, controllerName); err != nil {
217+
eventRecorder, err := events.NewRecorder(mgr, ctrl.Log, eventsAddr, controllerName)
218+
if err != nil {
220219
setupLog.Error(err, "unable to create event recorder")
221220
os.Exit(1)
222221
}

0 commit comments

Comments
 (0)