diff --git a/internal/controller/appwrapper/appwrapper_controller.go b/internal/controller/appwrapper/appwrapper_controller.go index 648d7a4..75990a2 100644 --- a/internal/controller/appwrapper/appwrapper_controller.go +++ b/internal/controller/appwrapper/appwrapper_controller.go @@ -32,7 +32,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/client-go/tools/record" + "k8s.io/client-go/tools/events" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -53,7 +53,7 @@ const ( // AppWrapperReconciler reconciles an appwrapper type AppWrapperReconciler struct { client.Client - Recorder record.EventRecorder + Recorder events.EventRecorder Scheme *runtime.Scheme Config *config.AppWrapperConfig } @@ -211,7 +211,7 @@ func (r *AppWrapperReconciler) Reconcile(ctx context.Context, req ctrl.Request) case awv1beta2.AppWrapperResuming: // deploying components if aw.Spec.Suspend { - r.Recorder.Event(aw, v1.EventTypeNormal, string(awv1beta2.AppWrapperSuspending), "Externally suspended while in the Resuming phase") + r.Recorder.Eventf(aw, nil, v1.EventTypeNormal, "ExternallySuspended", string(awv1beta2.AppWrapperSuspending), "Externally suspended while in the Resuming phase") return ctrl.Result{}, r.transitionToPhase(ctx, copyForStatusPatch(aw), aw, awv1beta2.AppWrapperSuspending) // abort deployment } err, fatal := r.createComponents(ctx, aw) // NOTE: createComponents applies patches to aw.Status incrementally as resources are created @@ -232,7 +232,7 @@ func (r *AppWrapperReconciler) Reconcile(ctx context.Context, req ctrl.Request) Reason: "CreateFailed", Message: detailMsg, }) - r.Recorder.Event(aw, v1.EventTypeNormal, string(awv1beta2.Unhealthy), "CreateFailed: "+detailMsg) + r.Recorder.Eventf(aw, nil, v1.EventTypeNormal, "CreateFailed", string(awv1beta2.Unhealthy), "%s", detailMsg) if fatal { return ctrl.Result{}, r.transitionToPhase(ctx, orig, aw, awv1beta2.AppWrapperFailed) // always move to failed on fatal error } else { @@ -244,7 +244,7 @@ func (r *AppWrapperReconciler) Reconcile(ctx context.Context, req ctrl.Request) case awv1beta2.AppWrapperRunning: // components deployed orig := copyForStatusPatch(aw) if aw.Spec.Suspend { - r.Recorder.Event(aw, v1.EventTypeNormal, string(awv1beta2.AppWrapperSuspending), "Externally suspended while in the Running phase") + r.Recorder.Eventf(aw, nil, v1.EventTypeNormal, "ExternallySuspended", string(awv1beta2.AppWrapperSuspending), "Externally suspended while in the Running phase") return ctrl.Result{}, r.transitionToPhase(ctx, orig, aw, awv1beta2.AppWrapperSuspending) // begin undeployment } @@ -267,7 +267,7 @@ func (r *AppWrapperReconciler) Reconcile(ctx context.Context, req ctrl.Request) Reason: "MissingComponent", Message: detailMsg, }) - r.Recorder.Event(aw, v1.EventTypeNormal, string(awv1beta2.Unhealthy), "MissingComponent: "+detailMsg) + r.Recorder.Eventf(aw, nil, v1.EventTypeNormal, "MissingComponent", string(awv1beta2.Unhealthy), "%s", detailMsg) return ctrl.Result{}, r.transitionToPhase(ctx, orig, aw, awv1beta2.AppWrapperFailed) } @@ -281,7 +281,7 @@ func (r *AppWrapperReconciler) Reconcile(ctx context.Context, req ctrl.Request) Reason: "FailedComponent", Message: detailMsg, }) - r.Recorder.Event(aw, v1.EventTypeNormal, string(awv1beta2.Unhealthy), "FailedComponent: "+detailMsg) + r.Recorder.Eventf(aw, nil, v1.EventTypeNormal, "FailedComponent", string(awv1beta2.Unhealthy), "%s", detailMsg) return ctrl.Result{}, r.resetOrFail(ctx, orig, aw, podStatus.terminalFailure, 1) } @@ -320,7 +320,7 @@ func (r *AppWrapperReconciler) Reconcile(ctx context.Context, req ctrl.Request) if now.Before(deadline) { return requeueAfter(deadline.Sub(now), r.Status().Patch(ctx, aw, client.MergeFrom(orig))) } else { - r.Recorder.Eventf(aw, v1.EventTypeNormal, string(awv1beta2.Unhealthy), "FoundFailedPods: %v failed pods", podStatus.failed) + r.Recorder.Eventf(aw, nil, v1.EventTypeNormal, "FoundFailedPods", string(awv1beta2.Unhealthy), "%v failed pods", podStatus.failed) return ctrl.Result{}, r.resetOrFail(ctx, orig, aw, podStatus.terminalFailure, 1) } } @@ -334,7 +334,7 @@ func (r *AppWrapperReconciler) Reconcile(ctx context.Context, req ctrl.Request) Reason: "AutopilotNoExecute", Message: detailMsg, }) - r.Recorder.Event(aw, v1.EventTypeNormal, string(awv1beta2.Unhealthy), detailMsg) + r.Recorder.Eventf(aw, nil, v1.EventTypeNormal, "AutopilotNoExecute", string(awv1beta2.Unhealthy), "%s", detailMsg) return ctrl.Result{}, r.resetOrFail(ctx, orig, aw, false, 0) // Autopilot triggered evacuation does not increment retry count } @@ -369,7 +369,7 @@ func (r *AppWrapperReconciler) Reconcile(ctx context.Context, req ctrl.Request) Reason: "InsufficientPodsReady", Message: podDetailsMessage, }) - r.Recorder.Event(aw, v1.EventTypeNormal, string(awv1beta2.Unhealthy), "InsufficientPodsReady: "+podDetailsMessage) + r.Recorder.Eventf(aw, nil, v1.EventTypeNormal, "InsufficientPodsReady", string(awv1beta2.Unhealthy), "%s", podDetailsMessage) return ctrl.Result{}, r.resetOrFail(ctx, orig, aw, podStatus.terminalFailure, 1) } @@ -400,7 +400,7 @@ func (r *AppWrapperReconciler) Reconcile(ctx context.Context, req ctrl.Request) case awv1beta2.AppWrapperResetting: orig := copyForStatusPatch(aw) if aw.Spec.Suspend { - r.Recorder.Event(aw, v1.EventTypeNormal, string(awv1beta2.AppWrapperSuspending), "Externally suspended while in the Resetting phase") + r.Recorder.Eventf(aw, nil, v1.EventTypeNormal, "ExternallySuspended", string(awv1beta2.AppWrapperSuspending), "Externally suspended while in the Resetting phase") return ctrl.Result{}, r.transitionToPhase(ctx, orig, aw, awv1beta2.AppWrapperSuspending) // Suspending trumps Resetting } diff --git a/internal/controller/appwrapper/appwrapper_controller_test.go b/internal/controller/appwrapper/appwrapper_controller_test.go index 2907a95..eb91a8e 100644 --- a/internal/controller/appwrapper/appwrapper_controller_test.go +++ b/internal/controller/appwrapper/appwrapper_controller_test.go @@ -24,7 +24,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" + "k8s.io/client-go/tools/events" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -66,7 +66,7 @@ var _ = Describe("AppWrapper Controller", func() { awReconciler = &AppWrapperReconciler{ Client: k8sClient, - Recorder: &record.FakeRecorder{}, + Recorder: &events.FakeRecorder{}, Scheme: k8sClient.Scheme(), Config: awConfig, } @@ -405,7 +405,7 @@ var _ = Describe("AppWrapper Annotations", func() { BeforeEach(func() { awReconciler = &AppWrapperReconciler{ Client: k8sClient, - Recorder: &record.FakeRecorder{}, + Recorder: &events.FakeRecorder{}, Scheme: k8sClient.Scheme(), Config: config.NewAppWrapperConfig(), } diff --git a/pkg/controller/setup.go b/pkg/controller/setup.go index 71be727..9091d31 100644 --- a/pkg/controller/setup.go +++ b/pkg/controller/setup.go @@ -44,9 +44,8 @@ func SetupControllers(mgr ctrl.Manager, awConfig *config.AppWrapperConfig) error } if err := (&appwrapper.AppWrapperReconciler{ - Client: mgr.GetClient(), - // TODO: migrate Event/Eventf call sites to k8s.io/client-go/tools/events.EventRecorder and switch to mgr.GetEventRecorder - Recorder: mgr.GetEventRecorderFor("appwrappers"), //nolint:staticcheck // SA1019: keep legacy events API until call sites are migrated + Client: mgr.GetClient(), + Recorder: mgr.GetEventRecorder("appwrappers"), Scheme: mgr.GetScheme(), Config: awConfig, }).SetupWithManager(mgr); err != nil {