From b0ad2dbca58b0975e495d1464d2b9b169298a238 Mon Sep 17 00:00:00 2001 From: Adrian Fernandez De La Torre Date: Fri, 19 Jun 2026 12:58:44 +0200 Subject: [PATCH] Adopt event/v1 API with actions and recorder Migrate from event/v1beta1 to event/v1 and replace the kuberecorder.EventRecorder with gotkevents.EventRecorder to support the richer event format including RelatedObject and Action fields. Signed-off-by: Adrian Fernandez De La Torre --- cmd/main.go | 16 ++++-------- .../artifactgenerator_controller.go | 26 +++++++++---------- .../artifactgenerator_controller_test.go | 5 ++-- ...ifactgenerator_direct_source_fetch_test.go | 2 +- .../controller/artifactgenerator_status.go | 3 ++- .../artifactgenerator_validation_test.go | 3 ++- internal/controller/suite_test.go | 14 ---------- internal/controller_test/suite_test.go | 2 +- 8 files changed, 27 insertions(+), 44 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 0541ae8b..dcdc4d85 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -27,7 +27,6 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" _ "k8s.io/client-go/plugin/pkg/client/auth" - "k8s.io/client-go/tools/record" "k8s.io/utils/ptr" ctrlruntime "sigs.k8s.io/controller-runtime" ctrlcache "sigs.k8s.io/controller-runtime/pkg/cache" @@ -201,7 +200,11 @@ func main() { // check will continue to fail until this controller instance is elected leader. gotkprobes.SetupChecks(mgr, setupLog) - eventRecorder := mustSetupEventRecorder(mgr, eventsAddr, controllerName) + eventRecorder, err := gotkevents.NewRecorder(mgr, ctrlruntime.Log, eventsAddr, controllerName) + if err != nil { + setupLog.Error(err, "unable to create event recorder") + os.Exit(1) + } // Register the ArtifactGenerator controller with the manager. if err = (&controller.ArtifactGeneratorReconciler{ @@ -245,12 +248,3 @@ func main() { os.Exit(1) } } - -func mustSetupEventRecorder(mgr ctrlruntime.Manager, eventsAddr, controllerName string) record.EventRecorder { - eventRecorder, err := gotkevents.NewRecorder(mgr, ctrlruntime.Log, eventsAddr, controllerName) - if err != nil { - setupLog.Error(err, "unable to create event recorder") - os.Exit(1) - } - return eventRecorder -} diff --git a/internal/controller/artifactgenerator_controller.go b/internal/controller/artifactgenerator_controller.go index dc6c1404..4b27df93 100644 --- a/internal/controller/artifactgenerator_controller.go +++ b/internal/controller/artifactgenerator_controller.go @@ -31,16 +31,16 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" kerrors "k8s.io/apimachinery/pkg/util/errors" - kuberecorder "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1" + eventv1 "github.com/fluxcd/pkg/apis/event/v1" gotkmeta "github.com/fluxcd/pkg/apis/meta" gotkstroage "github.com/fluxcd/pkg/artifact/storage" gotkfetch "github.com/fluxcd/pkg/http/fetch" gotkconditions "github.com/fluxcd/pkg/runtime/conditions" + gotkevents "github.com/fluxcd/pkg/runtime/events" gotkjitter "github.com/fluxcd/pkg/runtime/jitter" gotkpatch "github.com/fluxcd/pkg/runtime/patch" gotktar "github.com/fluxcd/pkg/tar" @@ -53,7 +53,7 @@ import ( // ArtifactGeneratorReconciler reconciles a ArtifactGenerator object. type ArtifactGeneratorReconciler struct { client.Client - kuberecorder.EventRecorder + gotkevents.EventRecorder ControllerName string Scheme *runtime.Scheme @@ -105,7 +105,7 @@ func (r *ArtifactGeneratorReconciler) Reconcile(ctx context.Context, req ctrl.Re // Pause reconciliation if the object has the reconcile annotation set to 'disabled'. if obj.IsDisabled() { log.Error(errors.New("can't reconcile"), msgReconciliationDisabled) - r.Event(obj, eventv1.EventTypeTrace, swapi.ReconciliationDisabledReason, msgReconciliationDisabled) + r.Eventf(obj, nil, eventv1.EventTypeTrace, swapi.ReconciliationDisabledReason, eventv1.ActionWaiting, "%s", msgReconciliationDisabled) return ctrl.Result{}, nil } @@ -146,7 +146,7 @@ func (r *ArtifactGeneratorReconciler) reconcile(ctx context.Context, gotkmeta.ReadyCondition, swapi.SourceFetchFailedReason, "%s", msg) - r.Event(obj, corev1.EventTypeWarning, swapi.SourceFetchFailedReason, msg) + r.Eventf(obj, nil, corev1.EventTypeWarning, swapi.SourceFetchFailedReason, eventv1.ActionFailed, "%s", msg) log.Error(err, "failed to get sources, retrying") return ctrl.Result{RequeueAfter: r.DependencyRequeueInterval}, nil } @@ -161,7 +161,7 @@ func (r *ArtifactGeneratorReconciler) reconcile(ctx context.Context, if !hasDrifted { msg := fmt.Sprintf("No drift detected, %d artifact(s) up to date", len(obj.Status.Inventory)) log.Info(msg) - r.Event(obj, eventv1.EventTypeTrace, gotkmeta.ReadyCondition, msg) + r.Eventf(obj, nil, eventv1.EventTypeTrace, gotkmeta.ReadyCondition, eventv1.ActionReconciled, "%s", msg) return ctrl.Result{RequeueAfter: obj.GetRequeueAfter()}, nil } @@ -188,7 +188,7 @@ func (r *ArtifactGeneratorReconciler) reconcile(ctx context.Context, gotkmeta.ReadyCondition, swapi.SourceFetchFailedReason, "%s", msg) - r.Event(obj, corev1.EventTypeWarning, swapi.SourceFetchFailedReason, msg) + r.Eventf(obj, nil, corev1.EventTypeWarning, swapi.SourceFetchFailedReason, eventv1.ActionFailed, "%s", msg) log.Error(err, "failed to fetch sources, retrying") return ctrl.Result{RequeueAfter: r.DependencyRequeueInterval}, nil } @@ -211,7 +211,7 @@ func (r *ArtifactGeneratorReconciler) reconcile(ctx context.Context, gotkmeta.ReadyCondition, gotkmeta.BuildFailedReason, "%s", msg) - r.Event(obj, corev1.EventTypeWarning, gotkmeta.BuildFailedReason, msg) + r.Eventf(obj, nil, corev1.EventTypeWarning, gotkmeta.BuildFailedReason, eventv1.ActionFailed, "%s", msg) return ctrl.Result{}, err } @@ -228,7 +228,7 @@ func (r *ArtifactGeneratorReconciler) reconcile(ctx context.Context, gotkmeta.ReadyCondition, gotkmeta.BuildFailedReason, "%s", msg) - r.Event(obj, corev1.EventTypeWarning, gotkmeta.BuildFailedReason, msg) + r.Eventf(obj, nil, corev1.EventTypeWarning, gotkmeta.BuildFailedReason, eventv1.ActionFailed, "%s", msg) return ctrl.Result{}, err } @@ -245,7 +245,7 @@ func (r *ArtifactGeneratorReconciler) reconcile(ctx context.Context, gotkmeta.ReadyCondition, gotkmeta.ReconciliationFailedReason, "%s", msg) - r.Event(obj, corev1.EventTypeWarning, gotkmeta.ReconciliationFailedReason, msg) + r.Eventf(obj, nil, corev1.EventTypeWarning, gotkmeta.ReconciliationFailedReason, eventv1.ActionFailed, "%s", msg) return ctrl.Result{}, err } eaRefs = append(eaRefs, *eaRef) @@ -275,7 +275,7 @@ func (r *ArtifactGeneratorReconciler) reconcile(ctx context.Context, gotkmeta.ReadyCondition, gotkmeta.SucceededReason, "%s", msg) - r.Event(obj, eventv1.EventTypeTrace, gotkmeta.ReadyCondition, msg) + r.Eventf(obj, nil, eventv1.EventTypeTrace, gotkmeta.ReadyCondition, eventv1.ActionReconciled, "%s", msg) r.notify(oldObj, obj, eaRefs) @@ -295,7 +295,7 @@ func (r *ArtifactGeneratorReconciler) notify(oldObj, newObj *swapi.ArtifactGener if len(eaChanged) > 0 { msg := fmt.Sprintf("external artifacts reconciled: %s", strings.Join(eaChanged, "\n")) - r.Event(newObj, corev1.EventTypeNormal, gotkmeta.ReadyCondition, msg) + r.Eventf(newObj, nil, corev1.EventTypeNormal, gotkmeta.ReadyCondition, eventv1.ActionReconciled, "%s", msg) } } @@ -526,7 +526,7 @@ func (r *ArtifactGeneratorReconciler) reconcileExternalArtifact(ctx context.Cont msg := fmt.Sprintf("%s/%s/%s reconciled with revision %s", ea.Kind, ea.Namespace, ea.Name, artifact.Revision) log.Info(msg) - r.Event(obj, eventv1.EventTypeTrace, gotkmeta.ReadyCondition, msg) + r.Eventf(obj, nil, eventv1.EventTypeTrace, gotkmeta.ReadyCondition, eventv1.ActionReconciled, "%s", msg) } return &swapi.ExternalArtifactReference{ diff --git a/internal/controller/artifactgenerator_controller_test.go b/internal/controller/artifactgenerator_controller_test.go index 3c5fe231..6e2a47cf 100644 --- a/internal/controller/artifactgenerator_controller_test.go +++ b/internal/controller/artifactgenerator_controller_test.go @@ -36,6 +36,7 @@ import ( gotkmeta "github.com/fluxcd/pkg/apis/meta" gotkconditions "github.com/fluxcd/pkg/runtime/conditions" + "github.com/fluxcd/pkg/runtime/testenv" gotktestsrv "github.com/fluxcd/pkg/testserver" sourcev1 "github.com/fluxcd/source-controller/api/v1" @@ -250,7 +251,7 @@ func TestArtifactGeneratorReconciler_Reconcile(t *testing.T) { g.Expect(updatedArtifact.Status.Artifact.Revision).To(Equal(ociRevision)) // Verify events were recorded - events := getEvents(obj.Name, obj.Namespace) + events := testenv.GetEvents(ctx, testClient, obj.Name, obj.Namespace, nil) g.Expect(events).ToNot(BeEmpty()) for _, e := range events { g.Expect(e.Type).To(Equal(corev1.EventTypeNormal)) @@ -701,7 +702,7 @@ func getArtifactGeneratorReconciler() *ArtifactGeneratorReconciler { Client: testClient, APIReader: testClient, Scheme: testEnv.Scheme(), - EventRecorder: testEnv.GetEventRecorderFor(controllerName), + EventRecorder: testEnv.GetEventRecorder(controllerName), Storage: testStorage, ArtifactFetchRetries: 1, DependencyRequeueInterval: 5 * time.Second, diff --git a/internal/controller/artifactgenerator_direct_source_fetch_test.go b/internal/controller/artifactgenerator_direct_source_fetch_test.go index f55da7a9..8281fba8 100644 --- a/internal/controller/artifactgenerator_direct_source_fetch_test.go +++ b/internal/controller/artifactgenerator_direct_source_fetch_test.go @@ -53,7 +53,7 @@ func TestArtifactGeneratorReconciler_DirectSourceFetch(t *testing.T) { Client: testClient, APIReader: testClient, Scheme: testEnv.Scheme(), - EventRecorder: testEnv.GetEventRecorderFor(controllerName), + EventRecorder: testEnv.GetEventRecorder(controllerName), Storage: testStorage, ArtifactFetchRetries: 1, DependencyRequeueInterval: 5 * time.Second, diff --git a/internal/controller/artifactgenerator_status.go b/internal/controller/artifactgenerator_status.go index 34354cad..34248469 100644 --- a/internal/controller/artifactgenerator_status.go +++ b/internal/controller/artifactgenerator_status.go @@ -25,6 +25,7 @@ import ( kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/reconcile" + eventv1 "github.com/fluxcd/pkg/apis/event/v1" gotkmeta "github.com/fluxcd/pkg/apis/meta" gotkconditions "github.com/fluxcd/pkg/runtime/conditions" gotkpatch "github.com/fluxcd/pkg/runtime/patch" @@ -104,6 +105,6 @@ func (r *ArtifactGeneratorReconciler) newTerminalErrorFor(obj *swapi.ArtifactGen terminalErr := fmt.Errorf(messageFormat, messageArgs...) gotkconditions.MarkFalse(obj, gotkmeta.ReadyCondition, reason, "%s", terminalErr.Error()) gotkconditions.MarkStalled(obj, reason, "%s", terminalErr.Error()) - r.Event(obj, corev1.EventTypeWarning, reason, terminalErr.Error()) + r.Eventf(obj, nil, corev1.EventTypeWarning, reason, eventv1.ActionFailed, "%s", terminalErr.Error()) return reconcile.TerminalError(terminalErr) } diff --git a/internal/controller/artifactgenerator_validation_test.go b/internal/controller/artifactgenerator_validation_test.go index 7d8cfde3..412af9e0 100644 --- a/internal/controller/artifactgenerator_validation_test.go +++ b/internal/controller/artifactgenerator_validation_test.go @@ -27,6 +27,7 @@ import ( gotkmeta "github.com/fluxcd/pkg/apis/meta" gotkconditions "github.com/fluxcd/pkg/runtime/conditions" + "github.com/fluxcd/pkg/runtime/testenv" swapi "github.com/fluxcd/source-watcher/api/v2/v1beta1" ) @@ -136,7 +137,7 @@ func TestArtifactGeneratorReconciler_specValidation(t *testing.T) { g.Expect(gotkconditions.GetReason(obj, gotkmeta.ReadyCondition)).To(Equal(tt.expectedReason)) // Verify event was recorded - events := getEvents(obj.Name, obj.Namespace) + events := testenv.GetEvents(ctx, testClient, obj.Name, obj.Namespace, nil) g.Expect(events).ToNot(BeEmpty()) g.Expect(events[0].Reason).To(Equal(tt.expectedReason)) }) diff --git a/internal/controller/suite_test.go b/internal/controller/suite_test.go index 2d127253..59cbf8c4 100644 --- a/internal/controller/suite_test.go +++ b/internal/controller/suite_test.go @@ -17,14 +17,12 @@ limitations under the License. package controller import ( - "context" "fmt" "os" "path/filepath" "testing" "time" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -136,15 +134,3 @@ func objToYaml(obj client.Object) string { } return fmt.Sprintf("---\n%s", string(yamlBytes)) } - -func getEvents(objName, objNamespace string) []corev1.Event { - var result []corev1.Event - events := &corev1.EventList{} - _ = testClient.List(context.Background(), events) - for _, event := range events.Items { - if event.InvolvedObject.Name == objName && event.InvolvedObject.Namespace == objNamespace { - result = append(result, event) - } - } - return result -} diff --git a/internal/controller_test/suite_test.go b/internal/controller_test/suite_test.go index 3ac1470e..0a8d86d3 100644 --- a/internal/controller_test/suite_test.go +++ b/internal/controller_test/suite_test.go @@ -136,7 +136,7 @@ func registerController() error { Client: testEnv.Manager.GetClient(), APIReader: testEnv.Manager.GetAPIReader(), Scheme: testEnv.Scheme(), - EventRecorder: testEnv.GetEventRecorderFor(controllerName), + EventRecorder: testEnv.GetEventRecorder(controllerName), Storage: testStorage, ArtifactFetchRetries: 1, DependencyRequeueInterval: 5 * time.Second,