diff --git a/internal/controller/kustomization_controller.go b/internal/controller/kustomization_controller.go index 1bf2204cf..af41fdb76 100644 --- a/internal/controller/kustomization_controller.go +++ b/internal/controller/kustomization_controller.go @@ -37,7 +37,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" 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" @@ -47,7 +46,7 @@ import ( "github.com/fluxcd/cli-utils/pkg/kstatus/polling/engine" "github.com/fluxcd/cli-utils/pkg/object" apiacl "github.com/fluxcd/pkg/apis/acl" - 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" authutils "github.com/fluxcd/pkg/auth/utils" @@ -59,6 +58,7 @@ import ( runtimeClient "github.com/fluxcd/pkg/runtime/client" "github.com/fluxcd/pkg/runtime/conditions" runtimeCtrl "github.com/fluxcd/pkg/runtime/controller" + "github.com/fluxcd/pkg/runtime/events" "github.com/fluxcd/pkg/runtime/jitter" "github.com/fluxcd/pkg/runtime/patch" "github.com/fluxcd/pkg/runtime/statusreaders" @@ -85,7 +85,7 @@ import ( // KustomizationReconciler reconciles a Kustomization object type KustomizationReconciler struct { client.Client - kuberecorder.EventRecorder + events.EventRecorder runtimeCtrl.Metrics // Kubernetes options @@ -157,7 +157,8 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques time.Since(reconcileStart).String(), obj.Spec.Interval.Duration.String()) log.Info(msg, "revision", obj.Status.LastAttemptedRevision) - r.event(obj, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, eventv1.EventSeverityInfo, msg, + r.event(obj, nil, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, eventv1.EventSeverityInfo, + eventv1.ActionReconciled, msg, map[string]string{ kustomizev1.GroupVersion.Group + "/" + eventv1.MetaCommitStatusKey: eventv1.MetaCommitStatusUpdateValue, }) @@ -166,7 +167,7 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques // Prune managed resources if the object is under deletion. if !obj.ObjectMeta.DeletionTimestamp.IsZero() { - return r.finalize(ctx, obj) + return r.finalize(ctx, obj, nil) } // Add finalizer first if it doesn't exist to avoid the race condition @@ -191,7 +192,7 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques conditions.MarkFalse(obj, meta.ReadyCondition, meta.InvalidCELExpressionReason, "%s", errMsg) conditions.MarkStalled(obj, meta.InvalidCELExpressionReason, "%s", errMsg) obj.Status.ObservedGeneration = obj.Generation - r.event(obj, "", "", eventv1.EventSeverityError, errMsg, nil) + r.event(obj, nil, "", "", eventv1.EventSeverityError, eventv1.ActionFailed, errMsg, nil) return ctrl.Result{}, reconcile.TerminalError(err) } @@ -203,7 +204,7 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques conditions.MarkFalse(obj, meta.ReadyCondition, meta.FeatureGateDisabledReason, msgFmt, gate) conditions.MarkStalled(obj, meta.FeatureGateDisabledReason, msgFmt, gate) log.Error(auth.ErrObjectLevelWorkloadIdentityNotEnabled, msg) - r.event(obj, "", "", eventv1.EventSeverityError, msg, nil) + r.event(obj, nil, "", "", eventv1.EventSeverityError, eventv1.ActionFailed, msg, nil) return ctrl.Result{}, nil } @@ -221,7 +222,7 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques if acl.IsAccessDenied(err) { conditions.MarkFalse(obj, meta.ReadyCondition, apiacl.AccessDeniedReason, "%s", err) conditions.MarkStalled(obj, apiacl.AccessDeniedReason, "%s", err) - r.event(obj, "", "", eventv1.EventSeverityError, err.Error(), nil) + r.event(obj, artifactSource, "", "", eventv1.EventSeverityError, eventv1.ActionFailed, err.Error(), nil) return ctrl.Result{}, reconcile.TerminalError(err) } @@ -248,7 +249,7 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques conditions.MarkFalse(obj, meta.ReadyCondition, meta.InvalidCELExpressionReason, "%s", errMsg) conditions.MarkStalled(obj, meta.InvalidCELExpressionReason, "%s", errMsg) obj.Status.ObservedGeneration = obj.Generation - r.event(obj, revision, originRevision, eventv1.EventSeverityError, errMsg, nil) + r.event(obj, artifactSource, revision, originRevision, eventv1.EventSeverityError, eventv1.ActionFailed, errMsg, nil) return ctrl.Result{}, err } @@ -256,7 +257,7 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques conditions.MarkFalse(obj, meta.ReadyCondition, meta.DependencyNotReadyReason, "%s", err) msg := fmt.Sprintf("Dependencies do not meet ready condition, retrying in %s", r.DependencyRequeueInterval.String()) log.Info(msg) - r.event(obj, revision, originRevision, eventv1.EventSeverityInfo, msg, nil) + r.event(obj, artifactSource, revision, originRevision, eventv1.EventSeverityInfo, eventv1.ActionWaiting, msg, nil) return ctrl.Result{RequeueAfter: r.DependencyRequeueInterval}, nil } log.Info("All dependencies are ready, proceeding with reconciliation") @@ -280,7 +281,7 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques meta.HealthCheckCanceledReason, "New reconciliation triggered by %s/%s/%s", qes.Kind, qes.Namespace, qes.Name) ctrl.LoggerFrom(ctx).Info("New reconciliation triggered, canceling health checks", "trigger", qes) - r.event(obj, revision, originRevision, eventv1.EventSeverityInfo, + r.event(obj, artifactSource, revision, originRevision, eventv1.EventSeverityInfo, eventv1.ActionProgressing, fmt.Sprintf("Health checks canceled due to new reconciliation triggered by %s/%s/%s", qes.Kind, qes.Namespace, qes.Name), nil) @@ -298,7 +299,7 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques obj.GetRetryInterval().String()), "revision", revision) - r.event(obj, revision, originRevision, eventv1.EventSeverityError, + r.event(obj, artifactSource, revision, originRevision, eventv1.EventSeverityError, eventv1.ActionFailed, reconcileErr.Error(), nil) return ctrl.Result{RequeueAfter: obj.GetRetryInterval()}, nil } @@ -468,7 +469,7 @@ func (r *KustomizationReconciler) reconcile( } // Validate and apply resources in stages. - drifted, changeSet, err := r.apply(ctx, resourceManager, obj, revision, originRevision, objects) + drifted, changeSet, err := r.apply(ctx, resourceManager, obj, src, revision, originRevision, objects) if err != nil { obj.Status.History.Upsert(checksum, time.Now(), time.Since(reconcileStart), meta.ReconciliationFailedReason, historyMeta) conditions.MarkFalse(obj, meta.ReadyCondition, meta.ReconciliationFailedReason, "%s", err) @@ -496,7 +497,7 @@ func (r *KustomizationReconciler) reconcile( } // Run garbage collection for stale resources that do not have pruning disabled. - if _, err := r.prune(ctx, resourceManager, obj, revision, originRevision, staleObjects); err != nil { + if _, err := r.prune(ctx, resourceManager, obj, src, revision, originRevision, staleObjects); err != nil { obj.Status.History.Upsert(checksum, time.Now(), time.Since(reconcileStart), meta.PruneFailedReason, historyMeta) conditions.MarkFalse(obj, meta.ReadyCondition, meta.PruneFailedReason, "%s", err) return err @@ -508,6 +509,7 @@ func (r *KustomizationReconciler) reconcile( resourceManager, patcher, obj, + src, revision, originRevision, isNewRevision, @@ -831,6 +833,7 @@ func (r *KustomizationReconciler) build(ctx context.Context, func (r *KustomizationReconciler) apply(ctx context.Context, manager *ssa.ResourceManager, obj *kustomizev1.Kustomization, + src sourcev1.Source, revision string, originRevision string, objects []*unstructured.Unstructured) (bool, *ssa.ChangeSet, error) { @@ -956,7 +959,7 @@ func (r *KustomizationReconciler) apply(ctx context.Context, // emit event only if the server-side apply resulted in changes applyLog := strings.TrimSuffix(changeSetLog.String(), "\n") if applyLog != "" { - r.event(obj, revision, originRevision, eventv1.EventSeverityInfo, applyLog, nil) + r.event(obj, src, revision, originRevision, eventv1.EventSeverityInfo, eventv1.ActionApplied, applyLog, nil) } return applyLog != "", resultSet, nil @@ -966,6 +969,7 @@ func (r *KustomizationReconciler) checkHealth(ctx context.Context, manager *ssa.ResourceManager, patcher *patch.SerialPatcher, obj *kustomizev1.Kustomization, + src sourcev1.Source, revision string, originRevision string, isNewRevision bool, @@ -1043,7 +1047,7 @@ func (r *KustomizationReconciler) checkHealth(ctx context.Context, // Emit recovery event if the previous health check failed. msg := fmt.Sprintf("Health check passed in %s", time.Since(checkStart).String()) if !wasHealthy || (isNewRevision && drifted) { - r.event(obj, revision, originRevision, eventv1.EventSeverityInfo, msg, nil) + r.event(obj, src, revision, originRevision, eventv1.EventSeverityInfo, eventv1.ActionReconciled, msg, nil) } conditions.MarkTrue(obj, meta.HealthyCondition, meta.SucceededReason, "%s", msg) @@ -1057,6 +1061,7 @@ func (r *KustomizationReconciler) checkHealth(ctx context.Context, func (r *KustomizationReconciler) prune(ctx context.Context, manager *ssa.ResourceManager, obj *kustomizev1.Kustomization, + src sourcev1.Source, revision string, originRevision string, objects []*unstructured.Unstructured) (bool, error) { @@ -1074,7 +1079,7 @@ func (r *KustomizationReconciler) prune(ctx context.Context, // emit event only if the prune operation resulted in changes if changeSet != nil && len(changeSet.Entries) > 0 { log.Info(fmt.Sprintf("garbage collection completed: %s", changeSet.String())) - r.event(obj, revision, originRevision, eventv1.EventSeverityInfo, changeSet.String(), nil) + r.event(obj, src, revision, originRevision, eventv1.EventSeverityInfo, eventv1.ActionDeleted, changeSet.String(), nil) return true, nil } @@ -1112,7 +1117,7 @@ func finalizerShouldDeleteResources(obj *kustomizev1.Kustomization) bool { // If the service account used for impersonation is no longer available or if a timeout occurs // while waiting for resources to be terminated, an error is logged and the finalizer is removed. func (r *KustomizationReconciler) finalize(ctx context.Context, - obj *kustomizev1.Kustomization) (ctrl.Result, error) { + obj *kustomizev1.Kustomization, src sourcev1.Source) (ctrl.Result, error) { log := ctrl.LoggerFrom(ctx) if finalizerShouldDeleteResources(obj) { objects, _ := inventory.List(obj.Status.Inventory) @@ -1153,14 +1158,16 @@ func (r *KustomizationReconciler) finalize(ctx context.Context, changeSet, err := deleteObjects(ctx, obj, resourceManager, objects) if err != nil { - r.event(obj, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, eventv1.EventSeverityError, "pruning for deleted resource failed", nil) + r.event(obj, src, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, + eventv1.EventSeverityError, eventv1.ActionFailed, "pruning for deleted resource failed", nil) // Return the error so we retry the failed garbage collection return ctrl.Result{}, err } if changeSet != nil && len(changeSet.Entries) > 0 { // Emit event with the resources marked for deletion. - r.event(obj, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, eventv1.EventSeverityInfo, changeSet.String(), nil) + r.event(obj, src, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, + eventv1.EventSeverityInfo, eventv1.ActionDeleted, changeSet.String(), nil) // Wait for the resources marked for deletion to be terminated. if obj.GetDeletionPolicy() == kustomizev1.DeletionPolicyWaitForTermination { @@ -1171,7 +1178,8 @@ func (r *KustomizationReconciler) finalize(ctx context.Context, // Emit an event and log the error if a timeout occurs. msg := "failed to wait for resources termination" log.Error(err, msg) - r.event(obj, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, eventv1.EventSeverityError, msg, nil) + r.event(obj, src, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, + eventv1.EventSeverityError, eventv1.ActionFailed, msg, nil) } } } @@ -1179,7 +1187,8 @@ func (r *KustomizationReconciler) finalize(ctx context.Context, // when the account to impersonate is gone, log the stale objects and continue with the finalization msg := fmt.Sprintf("unable to prune objects: \n%s", ssautil.FmtUnstructuredList(objects)) log.Error(fmt.Errorf("skiping pruning, failed to find account to impersonate"), msg) - r.event(obj, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, eventv1.EventSeverityError, msg, nil) + r.event(obj, src, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, + eventv1.EventSeverityError, eventv1.ActionFailed, msg, nil) } } @@ -1196,7 +1205,10 @@ func (r *KustomizationReconciler) finalize(ctx context.Context, } func (r *KustomizationReconciler) event(obj *kustomizev1.Kustomization, - revision, originRevision, severity, msg string, + src sourcev1.Source, + revision, originRevision, severity, + action string, + msg string, metadata map[string]string) { if metadata == nil { metadata = map[string]string{} @@ -1218,7 +1230,7 @@ func (r *KustomizationReconciler) event(obj *kustomizev1.Kustomization, eventType = corev1.EventTypeWarning } - r.EventRecorder.AnnotatedEventf(obj, metadata, eventType, reason, msg) + r.AnnotatedEventf(obj, src, metadata, eventType, reason, action, "%s", msg) } func (r *KustomizationReconciler) finalizeStatus(ctx context.Context, diff --git a/internal/controller/kustomization_controller_test.go b/internal/controller/kustomization_controller_test.go index b3672abee..e1637522e 100644 --- a/internal/controller/kustomization_controller_test.go +++ b/internal/controller/kustomization_controller_test.go @@ -22,18 +22,18 @@ import ( "testing" "time" - "github.com/fluxcd/pkg/apis/meta" - sourcev1 "github.com/fluxcd/source-controller/api/v1" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" + "github.com/fluxcd/pkg/apis/meta" + "github.com/fluxcd/pkg/runtime/events" + sourcev1 "github.com/fluxcd/source-controller/api/v1" ) func TestKustomizationReconciler_StagedApply(t *testing.T) { @@ -130,7 +130,7 @@ func TestKustomizationReconciler_deleteBeforeFinalizer(t *testing.T) { r := &KustomizationReconciler{ Client: k8sClient, - EventRecorder: record.NewFakeRecorder(32), + EventRecorder: events.NewFakeRecorder(32, true), } // NOTE: Only a real API server responds with an error in this scenario. _, err := r.Reconcile(ctx, ctrl.Request{NamespacedName: client.ObjectKeyFromObject(kustomization)}) diff --git a/internal/controller/kustomization_decryptor_test.go b/internal/controller/kustomization_decryptor_test.go index d4cdb91c3..c70224cdd 100644 --- a/internal/controller/kustomization_decryptor_test.go +++ b/internal/controller/kustomization_decryptor_test.go @@ -195,8 +195,8 @@ func TestKustomizationReconciler_Decryptor(t *testing.T) { events := getEvents(resultK.GetName(), map[string]string{"kustomize.toolkit.fluxcd.io/revision": revision}) g.Expect(len(events)).To(BeIdenticalTo(1)) - g.Expect(events[0].Message).Should(ContainSubstring("Reconciliation finished")) - g.Expect(events[0].Message).ShouldNot(ContainSubstring("configured")) + g.Expect(events[0].Note).Should(ContainSubstring("Reconciliation finished")) + g.Expect(events[0].Note).ShouldNot(ContainSubstring("configured")) }) t.Run("global SOPS age secret as fallback", func(t *testing.T) { diff --git a/internal/controller/kustomization_externalartifact_test.go b/internal/controller/kustomization_externalartifact_test.go index dedd8a502..b98c4de3d 100644 --- a/internal/controller/kustomization_externalartifact_test.go +++ b/internal/controller/kustomization_externalartifact_test.go @@ -122,11 +122,11 @@ stringData: events := getEvents(resultK.GetName(), map[string]string{"kustomize.toolkit.fluxcd.io/revision": revision}) g.Expect(len(events) > 2).To(BeTrue()) g.Expect(events[0].Reason).To(BeIdenticalTo(meta.ProgressingReason)) - g.Expect(events[0].Message).To(ContainSubstring("created")) + g.Expect(events[0].Note).To(ContainSubstring("created")) g.Expect(events[1].Reason).To(BeIdenticalTo(meta.ProgressingReason)) - g.Expect(events[1].Message).To(ContainSubstring("check passed")) + g.Expect(events[1].Note).To(ContainSubstring("check passed")) g.Expect(events[2].Reason).To(BeIdenticalTo(meta.ReconciliationSucceededReason)) - g.Expect(events[2].Message).To(ContainSubstring("finished")) + g.Expect(events[2].Note).To(ContainSubstring("finished")) }) t.Run("watches for external artifact revision change", func(t *testing.T) { @@ -164,7 +164,7 @@ stringData: events := getEvents(resultK.GetName(), nil) g.Expect(events[len(events)-1].Reason).To(BeIdenticalTo(apiacl.AccessDeniedReason)) - g.Expect(events[len(events)-1].Message).To(ContainSubstring("feature gate is disabled")) + g.Expect(events[len(events)-1].Note).To(ContainSubstring("feature gate is disabled")) }) } diff --git a/internal/controller/kustomization_force_test.go b/internal/controller/kustomization_force_test.go index 7d8654cc8..e8a502511 100644 --- a/internal/controller/kustomization_force_test.go +++ b/internal/controller/kustomization_force_test.go @@ -144,7 +144,7 @@ stringData: events := getEvents(resultK.GetName(), map[string]string{"kustomize.toolkit.fluxcd.io/revision": revision}) g.Expect(len(events) > 0).To(BeTrue()) g.Expect(events[0].Type).To(BeIdenticalTo("Warning")) - g.Expect(events[0].Message).To(ContainSubstring("field is immutable")) + g.Expect(events[0].Note).To(ContainSubstring("field is immutable")) }) }) diff --git a/internal/controller/kustomization_fuzzer_test.go b/internal/controller/kustomization_fuzzer_test.go index d895f0392..0fd75dad1 100644 --- a/internal/controller/kustomization_fuzzer_test.go +++ b/internal/controller/kustomization_fuzzer_test.go @@ -43,6 +43,7 @@ import ( "github.com/opencontainers/go-digest" "github.com/ory/dockertest/v3" corev1 "k8s.io/api/core/v1" + eventsv1 "k8s.io/api/events/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" utilruntime "k8s.io/apimachinery/pkg/util/runtime" @@ -562,12 +563,12 @@ func randStringRunes(n int) string { return string(b) } -func getEvents(objName string, annotations map[string]string) []corev1.Event { - var result []corev1.Event - events := &corev1.EventList{} +func getEvents(objName string, annotations map[string]string) []eventsv1.Event { + var result []eventsv1.Event + events := &eventsv1.EventList{} _ = k8sClient.List(ctx, events) for _, event := range events.Items { - if event.InvolvedObject.Name == objName { + if event.Regarding.Name == objName { if annotations == nil && len(annotations) == 0 { result = append(result, event) } else { diff --git a/internal/controller/kustomization_origin_revision_test.go b/internal/controller/kustomization_origin_revision_test.go index 5307f69f4..5db744188 100644 --- a/internal/controller/kustomization_origin_revision_test.go +++ b/internal/controller/kustomization_origin_revision_test.go @@ -22,7 +22,7 @@ import ( "testing" "time" - 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/testserver" sourcev1 "github.com/fluxcd/source-controller/api/v1" diff --git a/internal/controller/kustomization_wait_test.go b/internal/controller/kustomization_wait_test.go index fa8813799..889f54324 100644 --- a/internal/controller/kustomization_wait_test.go +++ b/internal/controller/kustomization_wait_test.go @@ -24,7 +24,7 @@ import ( runtimeClient "github.com/fluxcd/pkg/runtime/client" . "github.com/onsi/gomega" - corev1 "k8s.io/api/core/v1" + eventsv1 "k8s.io/api/events/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -210,7 +210,7 @@ parameters: events := getEvents(resultK.GetName(), map[string]string{"kustomize.toolkit.fluxcd.io/revision": revision}) g.Expect(len(events) > 0).To(BeTrue()) g.Expect(events[len(events)-1].Type).To(BeIdenticalTo("Warning")) - g.Expect(events[len(events)-1].Message).To(ContainSubstring("does-not-exists")) + g.Expect(events[len(events)-1].Note).To(ContainSubstring("does-not-exists")) }) t.Run("recovers and reports healthy status", func(t *testing.T) { @@ -252,7 +252,7 @@ parameters: events := getEvents(resultK.GetName(), map[string]string{"kustomize.toolkit.fluxcd.io/revision": revision}) g.Expect(len(events) > 1).To(BeTrue()) g.Expect(events[len(events)-2].Type).To(BeIdenticalTo("Normal")) - g.Expect(events[len(events)-2].Message).To(ContainSubstring(expectedMessage)) + g.Expect(events[len(events)-2].Note).To(ContainSubstring(expectedMessage)) }) t.Run("reports new revision healthy status", func(t *testing.T) { @@ -287,7 +287,7 @@ parameters: events := getEvents(resultK.GetName(), map[string]string{"kustomize.toolkit.fluxcd.io/revision": revision}) g.Expect(len(events) > 1).To(BeTrue()) g.Expect(events[len(events)-2].Type).To(BeIdenticalTo("Normal")) - g.Expect(events[len(events)-2].Message).To(ContainSubstring(expectedMessage)) + g.Expect(events[len(events)-2].Note).To(ContainSubstring(expectedMessage)) }) t.Run("finalizes object", func(t *testing.T) { @@ -749,7 +749,7 @@ spec: events := getEvents(resultK.GetName(), nil) for _, event := range events { if event.Reason == meta.HealthCheckCanceledReason { - t.Logf("Found HealthCheckCanceled event: %s", event.Message) + t.Logf("Found HealthCheckCanceled event: %s", event.Note) return true } } @@ -758,7 +758,7 @@ spec: // Verify the event message indicates the trigger source. events := getEvents(resultK.GetName(), nil) - var cancelEvent *corev1.Event + var cancelEvent *eventsv1.Event for i := range events { if events[i].Reason == meta.HealthCheckCanceledReason { cancelEvent = &events[i] @@ -766,8 +766,8 @@ spec: } } g.Expect(cancelEvent).ToNot(BeNil()) - g.Expect(cancelEvent.Message).To(ContainSubstring("Health checks canceled")) - g.Expect(cancelEvent.Message).To(ContainSubstring("GitRepository")) + g.Expect(cancelEvent.Note).To(ContainSubstring("Health checks canceled")) + g.Expect(cancelEvent.Note).To(ContainSubstring("GitRepository")) } func TestKustomizationReconciler_HealthCheckExprs_GroupOnly(t *testing.T) { diff --git a/internal/controller/suite_test.go b/internal/controller/suite_test.go index 470d549c8..b8f424351 100644 --- a/internal/controller/suite_test.go +++ b/internal/controller/suite_test.go @@ -29,6 +29,7 @@ import ( "github.com/opencontainers/go-digest" "github.com/ory/dockertest/v3" corev1 "k8s.io/api/core/v1" + eventsv1 "k8s.io/api/events/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes/scheme" @@ -44,6 +45,7 @@ import ( "github.com/fluxcd/pkg/runtime/conditions" kcheck "github.com/fluxcd/pkg/runtime/conditions/check" "github.com/fluxcd/pkg/runtime/controller" + "github.com/fluxcd/pkg/runtime/events" "github.com/fluxcd/pkg/runtime/metrics" "github.com/fluxcd/pkg/runtime/testenv" "github.com/fluxcd/pkg/testserver" @@ -136,12 +138,12 @@ func runInContext(registerControllers func(*testenv.Environment), run func() int code = run() if debugMode { - events := &corev1.EventList{} + events := &eventsv1.EventList{} _ = k8sClient.List(ctx, events) for _, event := range events.Items { fmt.Printf("%s %s \n%s\n", - event.InvolvedObject.Name, event.GetAnnotations()["kustomize.toolkit.fluxcd.io/revision"], - event.Message) + event.Regarding.Name, event.GetAnnotations()["kustomize.toolkit.fluxcd.io/revision"], + event.Note) } } @@ -179,7 +181,7 @@ func TestMain(m *testing.M) { Client: testEnv, Mapper: testEnv.GetRESTMapper(), APIReader: testEnv, - EventRecorder: testEnv.GetEventRecorderFor(controllerName), + EventRecorder: createMockEventRecorder(testEnv, controllerName), Metrics: testMetricsH, DependencyRequeueInterval: 2 * time.Second, ConcurrentSSA: 4, @@ -198,6 +200,15 @@ func TestMain(m *testing.M) { os.Exit(code) } +func createMockEventRecorder(testEnv *testenv.Environment, controllerName string) events.EventRecorder { + logger := ctrl.Log.WithName("events") + eventRecorder, err := events.NewRecorder(testEnv, logger, "", controllerName) + if err != nil { + panic(fmt.Sprintf("Failed to create event recorder: %v", err)) + } + return eventRecorder +} + var letterRunes = []rune("abcdefghijklmnopqrstuvwxyz1234567890") func randStringRunes(n int) string { @@ -241,12 +252,12 @@ func logStatus(t *testing.T, k *kustomizev1.Kustomization) { t.Log(string(sts)) } -func getEvents(objName string, annotations map[string]string) []corev1.Event { - var result []corev1.Event - events := &corev1.EventList{} +func getEvents(objName string, annotations map[string]string) []eventsv1.Event { + var result []eventsv1.Event + events := &eventsv1.EventList{} _ = k8sClient.List(ctx, events) for _, event := range events.Items { - if event.InvolvedObject.Name == objName { + if event.Regarding.Name == objName { if annotations == nil && len(annotations) == 0 { result = append(result, event) } else { diff --git a/main.go b/main.go index 85310f135..42d56fbc1 100644 --- a/main.go +++ b/main.go @@ -249,8 +249,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) }