Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions pkg/multicluster/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/tools/events"
"k8s.io/client-go/tools/record"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/cluster"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/recorder"

"github.com/cobaltcore-dev/cortex/api/v1alpha1"
)
Expand Down Expand Up @@ -81,7 +81,7 @@ type fakeCluster struct {
cluster.Cluster
fakeClient client.Client
fakeCache *fakeCache
fakeRecorder events.EventRecorder
fakeRecorder recorder.EventRecorder
scheme *runtime.Scheme
}

Expand All @@ -104,7 +104,7 @@ func (f *fakeCluster) GetFieldIndexer() client.FieldIndexer {
return f.fakeCache
}

func (f *fakeCluster) GetEventRecorder(_ string) events.EventRecorder {
func (f *fakeCluster) GetEventRecorder(_ string) recorder.EventRecorder {
if f.fakeRecorder != nil {
return f.fakeRecorder
}
Expand Down
25 changes: 16 additions & 9 deletions pkg/multicluster/recorder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,29 @@ package multicluster

import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/events"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cluster"
"sigs.k8s.io/controller-runtime/pkg/recorder"
)

// MultiClusterRecorder implements events.EventRecorder and routes events to the
// correct cluster based on the GVK of the "regarding" object. It uses the same
// routing logic as the multicluster Client's write path.
// MultiClusterRecorder implements recorder.EventRecorder and routes events to
// the correct cluster based on the GVK of the "regarding" object. It uses the
// same routing logic as the multicluster Client's write path.
type MultiClusterRecorder struct {
client *Client
homeRecorder events.EventRecorder
recorders map[cluster.Cluster]events.EventRecorder
homeRecorder recorder.EventRecorder
recorders map[cluster.Cluster]recorder.EventRecorder
}

// GetEventRecorder creates a multi-cluster-aware EventRecorder. It pre-creates
// a per-cluster recorder for the home cluster and every remote cluster currently
// registered in the client. The name parameter is passed through to each
// cluster's GetEventRecorder method (it becomes the reportingController in the
// Kubernetes Event).
func (c *Client) GetEventRecorder(name string) events.EventRecorder {
func (c *Client) GetEventRecorder(name string) recorder.EventRecorder {
homeRecorder := c.HomeCluster.GetEventRecorder(name)

recorders := make(map[cluster.Cluster]events.EventRecorder)
recorders := make(map[cluster.Cluster]recorder.EventRecorder)
recorders[c.HomeCluster] = homeRecorder

c.remoteClustersMu.RLock()
Expand Down Expand Up @@ -55,8 +55,15 @@ func (r *MultiClusterRecorder) Eventf(regarding, related runtime.Object, eventty
recorder.Eventf(regarding, related, eventtype, reason, action, note, args...)
}

// AnnotatedEventf routes the annotated event to the cluster that owns the
// "regarding" object. Falls back to the home cluster recorder if routing fails.
func (r *MultiClusterRecorder) AnnotatedEventf(regarding, related runtime.Object, annotations map[string]string, eventtype, reason, action, note string, args ...any) {
recorder := r.recorderFor(regarding)
recorder.AnnotatedEventf(regarding, related, annotations, eventtype, reason, action, note, args...)
}

// recorderFor resolves which per-cluster recorder to use for the given object.
func (r *MultiClusterRecorder) recorderFor(obj runtime.Object) events.EventRecorder {
func (r *MultiClusterRecorder) recorderFor(obj runtime.Object) recorder.EventRecorder {
if obj == nil {
return r.homeRecorder
}
Expand Down
12 changes: 12 additions & 0 deletions pkg/multicluster/recorder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ func (f *fakeEventRecorder) Eventf(regarding, _ runtime.Object, eventtype, reaso
})
}

func (f *fakeEventRecorder) AnnotatedEventf(regarding, _ runtime.Object, _ map[string]string, eventtype, reason, action, note string, args ...any) {
f.mu.Lock()
defer f.mu.Unlock()
f.calls = append(f.calls, eventfCall{
regarding: regarding,
eventtype: eventtype,
reason: reason,
action: action,
note: fmt.Sprintf(note, args...),
})
}

func (f *fakeEventRecorder) getCalls() []eventfCall {
f.mu.Lock()
defer f.mu.Unlock()
Expand Down