diff --git a/internal/controller/imagepolicy_controller.go b/internal/controller/imagepolicy_controller.go index 1b052c27..3ec28717 100644 --- a/internal/controller/imagepolicy_controller.go +++ b/internal/controller/imagepolicy_controller.go @@ -29,7 +29,6 @@ import ( "k8s.io/apimachinery/pkg/types" kerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/wait" - kuberecorder "k8s.io/client-go/tools/record" "k8s.io/client-go/util/retry" "k8s.io/client-go/util/workqueue" ctrl "sigs.k8s.io/controller-runtime" @@ -49,6 +48,7 @@ import ( "github.com/fluxcd/pkg/runtime/acl" "github.com/fluxcd/pkg/runtime/conditions" helper "github.com/fluxcd/pkg/runtime/controller" + "github.com/fluxcd/pkg/runtime/events" "github.com/fluxcd/pkg/runtime/patch" "github.com/fluxcd/pkg/runtime/predicates" pkgreconcile "github.com/fluxcd/pkg/runtime/reconcile" @@ -104,7 +104,7 @@ const imageRepoKey = ".spec.imageRepository" // ImagePolicyReconciler reconciles a ImagePolicy object type ImagePolicyReconciler struct { client.Client - kuberecorder.EventRecorder + events.EventRecorder helper.Metrics ControllerName string @@ -290,7 +290,7 @@ func (r *ImagePolicyReconciler) reconcile(ctx context.Context, sp *patch.SerialP conditions.Set(obj, reconciling) } - notify(ctx, r.EventRecorder, oldObj, obj, readyMsg) + notify(r.EventRecorder, oldObj, obj, readyMsg) }() // Validate errors in the spec before proceeding. diff --git a/internal/controller/imagepolicy_controller_test.go b/internal/controller/imagepolicy_controller_test.go index f23ffbb0..4505b023 100644 --- a/internal/controller/imagepolicy_controller_test.go +++ b/internal/controller/imagepolicy_controller_test.go @@ -30,7 +30,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" utilruntime "k8s.io/apimachinery/pkg/util/runtime" - "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/client/fake" @@ -41,6 +40,7 @@ import ( "github.com/fluxcd/pkg/auth" "github.com/fluxcd/pkg/runtime/acl" "github.com/fluxcd/pkg/runtime/conditions" + "github.com/fluxcd/pkg/runtime/events" "github.com/fluxcd/pkg/runtime/patch" imagev1 "github.com/fluxcd/image-reflector-controller/api/v1" @@ -540,7 +540,7 @@ func TestImagePolicyReconciler_intervalNotConfigured(t *testing.T) { r := &ImagePolicyReconciler{ Client: k8sClient, - EventRecorder: record.NewFakeRecorder(32), + EventRecorder: events.NewFakeRecorder(32, false), } obj := &imagev1.ImagePolicy{ @@ -632,7 +632,7 @@ func TestImagePolicyReconciler_deleteBeforeFinalizer(t *testing.T) { r := &ImagePolicyReconciler{ Client: k8sClient, - EventRecorder: record.NewFakeRecorder(32), + EventRecorder: events.NewFakeRecorder(32, false), } // NOTE: Only a real API server responds with an error in this scenario. _, err := r.Reconcile(ctx, ctrl.Request{NamespacedName: client.ObjectKeyFromObject(imagePolicy)}) @@ -805,7 +805,7 @@ func TestImagePolicyReconciler_getImageRepository(t *testing.T) { clientBuilder.WithObjects(imagePolicyNS, imageRepoNS, imageRepo) r := &ImagePolicyReconciler{ - EventRecorder: record.NewFakeRecorder(32), + EventRecorder: events.NewFakeRecorder(32, false), Client: clientBuilder.Build(), ACLOptions: tt.aclOpts, patchOptions: getPatchOptions(imagePolicyOwnedConditions, "irc"), @@ -1104,7 +1104,7 @@ func TestImagePolicyReconciler_digestReflection(t *testing.T) { ).To(Succeed(), "failed getting image repo") r := &ImagePolicyReconciler{ - EventRecorder: record.NewFakeRecorder(32), + EventRecorder: events.NewFakeRecorder(32, false), Client: c, Database: &mockDatabase{TagData: imageRepo.Status.LastScanResult.LatestTags}, AuthOptionsGetter: ®istry.AuthOptionsGetter{Client: c}, @@ -1260,7 +1260,7 @@ func TestImagePolicyReconciler_applyPolicy(t *testing.T) { g := NewWithT(t) r := &ImagePolicyReconciler{ - EventRecorder: record.NewFakeRecorder(32), + EventRecorder: events.NewFakeRecorder(32, false), Database: tt.db, patchOptions: getPatchOptions(imagePolicyOwnedConditions, "irc"), } diff --git a/internal/controller/imagerepository_controller.go b/internal/controller/imagerepository_controller.go index 8a2ad38d..03098518 100644 --- a/internal/controller/imagerepository_controller.go +++ b/internal/controller/imagerepository_controller.go @@ -18,7 +18,6 @@ package controller import ( "context" - "errors" "fmt" "regexp" "slices" @@ -30,9 +29,7 @@ import ( corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" 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" "k8s.io/client-go/util/workqueue" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" @@ -42,12 +39,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/predicate" ctrreconcile "sigs.k8s.io/controller-runtime/pkg/reconcile" - eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1" + eventv1 "github.com/fluxcd/pkg/apis/event/v1" "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/auth" "github.com/fluxcd/pkg/cache" "github.com/fluxcd/pkg/runtime/conditions" helper "github.com/fluxcd/pkg/runtime/controller" + "github.com/fluxcd/pkg/runtime/events" "github.com/fluxcd/pkg/runtime/patch" "github.com/fluxcd/pkg/runtime/predicates" "github.com/fluxcd/pkg/runtime/reconcile" @@ -104,7 +102,7 @@ func getPatchOptions(ownedConditions []string, controllerName string) []patch.Op // ImageRepositoryReconciler reconciles a ImageRepository object type ImageRepositoryReconciler struct { client.Client - kuberecorder.EventRecorder + events.EventRecorder helper.Metrics ControllerName string @@ -229,7 +227,7 @@ func (r *ImageRepositoryReconciler) reconcile(ctx context.Context, sp *patch.Ser conditions.Set(obj, reconciling) } - notify(ctx, r.EventRecorder, oldObj, obj, nextScanMsg) + notify(r.EventRecorder, oldObj, obj, nextScanMsg) }() // Check object-level workload identity feature gate. @@ -470,22 +468,6 @@ func (r *ImageRepositoryReconciler) reconcileDelete(obj *imagev1.ImageRepository return ctrl.Result{}, nil } -// eventLogf records events, and logs at the same time. -// -// This log is different from the debug log in the EventRecorder, in the sense -// that this is a simple log. While the debug log contains complete details -// about the event. -func eventLogf(ctx context.Context, r kuberecorder.EventRecorder, obj runtime.Object, eventType string, reason string, messageFmt string, args ...interface{}) { - msg := fmt.Sprintf(messageFmt, args...) - // Log and emit event. - if eventType == corev1.EventTypeWarning { - ctrl.LoggerFrom(ctx).Error(errors.New(reason), msg) - } else { - ctrl.LoggerFrom(ctx).Info(msg) - } - r.Eventf(obj, eventType, reason, "%s", msg) -} - // filterOutTags filters the given tags through the given regular expression // patterns and returns a list of tags that don't match with the pattern. func filterOutTags(tags []string, patterns []string) ([]string, error) { @@ -550,13 +532,13 @@ func isEqualSliceContent(a, b []string) bool { // notify emits events, logs and notification based on the resulting objects // before and after the reconciliation. -func notify(ctx context.Context, r kuberecorder.EventRecorder, oldObj, newObj conditions.Setter, nextScanMsg string) { +func notify(r events.EventRecorder, oldObj, newObj conditions.Setter, nextScanMsg string) { ready := conditions.Get(newObj, meta.ReadyCondition) // Was ready before and is ready now, but the scan results have changed. if conditions.IsReady(oldObj) && conditions.IsReady(newObj) && (conditions.GetMessage(oldObj, meta.ReadyCondition)) != ready.Message { - eventLogf(ctx, r, newObj, corev1.EventTypeNormal, ready.Reason, "%s", ready.Message) + r.Eventf(newObj, nil, corev1.EventTypeNormal, ready.Reason, "", "%s", ready.Message) return } @@ -564,14 +546,13 @@ func notify(ctx context.Context, r kuberecorder.EventRecorder, oldObj, newObj co // Became ready from not ready. if !conditions.IsReady(oldObj) && conditions.IsReady(newObj) { - eventLogf(ctx, r, newObj, corev1.EventTypeNormal, ready.Reason, "%s", ready.Message) + r.Eventf(newObj, nil, corev1.EventTypeNormal, ready.Reason, "", "%s", ready.Message) return } // Not ready, failed. if !conditions.IsReady(newObj) { - eventLogf(ctx, r, newObj, corev1.EventTypeWarning, ready.Reason, "%s", ready.Message) + r.Eventf(newObj, nil, corev1.EventTypeWarning, ready.Reason, "", "%s", ready.Message) return } - - eventLogf(ctx, r, newObj, eventv1.EventTypeTrace, meta.SucceededReason, "%s", nextScanMsg) + r.Eventf(newObj, nil, eventv1.EventTypeTrace, meta.SucceededReason, "", "%s", nextScanMsg) } diff --git a/internal/controller/imagerepository_controller_test.go b/internal/controller/imagerepository_controller_test.go index db22c6bb..2d712bbe 100644 --- a/internal/controller/imagerepository_controller_test.go +++ b/internal/controller/imagerepository_controller_test.go @@ -35,13 +35,13 @@ import ( . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "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/client/fake" "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/runtime/conditions" + "github.com/fluxcd/pkg/runtime/events" "github.com/fluxcd/pkg/runtime/patch" "github.com/fluxcd/pkg/runtime/secrets" @@ -101,7 +101,7 @@ func TestImageRepositoryReconciler_deleteBeforeFinalizer(t *testing.T) { r := &ImageRepositoryReconciler{ Client: k8sClient, - EventRecorder: record.NewFakeRecorder(32), + EventRecorder: events.NewFakeRecorder(32, false), } // NOTE: Only a real API server responds with an error in this scenario. _, err := r.Reconcile(ctx, ctrl.Request{NamespacedName: client.ObjectKeyFromObject(imagerepo)}) @@ -248,7 +248,7 @@ func TestImageRepositoryReconciler_shouldScan(t *testing.T) { g := NewWithT(t) r := &ImageRepositoryReconciler{ - EventRecorder: record.NewFakeRecorder(32), + EventRecorder: events.NewFakeRecorder(32, false), Database: tt.db, patchOptions: getPatchOptions(imageRepositoryOwnedConditions, "irc"), } @@ -369,7 +369,7 @@ func TestImageRepositoryReconciler_scan(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) r := ImageRepositoryReconciler{ - EventRecorder: record.NewFakeRecorder(32), + EventRecorder: events.NewFakeRecorder(32, false), Database: tt.db, patchOptions: getPatchOptions(imageRepositoryOwnedConditions, "irc"), } @@ -605,7 +605,7 @@ func TestNotify(t *testing.T) { t.Run(tt.name, func(t *testing.T) { g := NewWithT(t) - recorder := record.NewFakeRecorder(32) + recorder := events.NewFakeRecorder(32, false) oldObj := &imagev1.ImageRepository{} newObj := oldObj.DeepCopy() @@ -614,7 +614,7 @@ func TestNotify(t *testing.T) { tt.beforeFunc(oldObj, newObj) } - notify(context.TODO(), recorder, oldObj, newObj, nextScanMsg) + notify(recorder, oldObj, newObj, nextScanMsg) select { case x, ok := <-recorder.Events: @@ -699,7 +699,7 @@ func TestImageRepositoryReconciler_TLS(t *testing.T) { Build() r := &ImageRepositoryReconciler{ - EventRecorder: record.NewFakeRecorder(32), + EventRecorder: events.NewFakeRecorder(32, false), Client: client, patchOptions: getPatchOptions(imageRepositoryOwnedConditions, "irc"), Database: &mockDatabase{}, diff --git a/internal/controller/policy_test.go b/internal/controller/policy_test.go index 0da1956d..00736bf6 100644 --- a/internal/controller/policy_test.go +++ b/internal/controller/policy_test.go @@ -25,7 +25,6 @@ import ( apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" aclapi "github.com/fluxcd/pkg/apis/acl" @@ -33,6 +32,7 @@ import ( "github.com/fluxcd/pkg/runtime/acl" "github.com/fluxcd/pkg/runtime/conditions" conditionscheck "github.com/fluxcd/pkg/runtime/conditions/check" + "github.com/fluxcd/pkg/runtime/events" "github.com/fluxcd/pkg/runtime/patch" imagev1 "github.com/fluxcd/image-reflector-controller/api/v1" @@ -119,7 +119,7 @@ func TestImagePolicyReconciler_crossNamespaceRefsDisallowed(t *testing.T) { r := &ImagePolicyReconciler{ Client: builder.Build(), Database: database.NewBadgerDatabase(testBadgerDB), - EventRecorder: record.NewFakeRecorder(32), + EventRecorder: events.NewFakeRecorder(32, false), ACLOptions: acl.Options{ NoCrossNamespaceRefs: true, }, diff --git a/internal/controller/suite_test.go b/internal/controller/suite_test.go index ad43ce94..291c9d26 100644 --- a/internal/controller/suite_test.go +++ b/internal/controller/suite_test.go @@ -27,12 +27,12 @@ import ( "github.com/dgraph-io/badger/v4" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/yaml" "github.com/fluxcd/pkg/runtime/controller" + "github.com/fluxcd/pkg/runtime/events" "github.com/fluxcd/pkg/runtime/testenv" imagev1 "github.com/fluxcd/image-reflector-controller/api/v1" @@ -92,7 +92,7 @@ func TestMain(m *testing.M) { if err = (&ImageRepositoryReconciler{ Client: testEnv, Database: database.NewBadgerDatabase(testBadgerDB), - EventRecorder: record.NewFakeRecorder(256), + EventRecorder: events.NewFakeRecorder(256, false), AuthOptionsGetter: optGetter, }).SetupWithManager(testEnv, ImageRepositoryReconcilerOptions{ RateLimiter: controller.GetDefaultRateLimiter(), @@ -103,7 +103,7 @@ func TestMain(m *testing.M) { if err = (&ImagePolicyReconciler{ Client: testEnv, Database: database.NewBadgerDatabase(testBadgerDB), - EventRecorder: record.NewFakeRecorder(256), + EventRecorder: events.NewFakeRecorder(256, false), AuthOptionsGetter: optGetter, DependencyRequeueInterval: 30 * time.Second, }).SetupWithManager(testEnv, ImagePolicyReconcilerOptions{ diff --git a/main.go b/main.go index f02887e2..ab1825b6 100644 --- a/main.go +++ b/main.go @@ -244,8 +244,8 @@ func main() { probes.SetupChecks(mgr, setupLog) - var eventRecorder *events.Recorder - if eventRecorder, err = events.NewRecorder(mgr, ctrl.Log, eventsAddr, controllerName); err != nil { + eventRecorder, err := events.NewRecorder(mgr, ctrl.Log, eventsAddr, controllerName) + if err != nil { setupLog.Error(err, "unable to create event recorder") os.Exit(1) }