Skip to content

Commit 27afc01

Browse files
committed
Migrate to new Kubernentes event API
Signed-off-by: Adrian Fernandez De La Torre <adri1197@gmail.com>
1 parent 07d627d commit 27afc01

6 files changed

Lines changed: 183 additions & 83 deletions

File tree

apis/event/v1beta1/action.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
Copyright 2022 The Flux authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1beta1
18+
19+
// These constants define common event actions used throughout Flux controllers.
20+
const (
21+
// ActionReconciling indicates a reconciliation is in progress.
22+
ActionReconciling string = "Reconciling"
23+
// ActionReconciled indicates a successful reconciliation.
24+
ActionReconciled string = "Reconciled"
25+
// ActionFetching indicates fetching of a resource or artifact.
26+
ActionFetching string = "Fetching"
27+
// ActionFetched indicates successful fetch of a resource or artifact.
28+
ActionFetched string = "Fetched"
29+
// ActionApplying indicates applying changes to the cluster.
30+
ActionApplying string = "Applying"
31+
// ActionApplied indicates successful application of changes.
32+
ActionApplied string = "Applied"
33+
// ActionDeleting indicates deletion is in progress.
34+
ActionDeleting string = "Deleting"
35+
// ActionDeleted indicates successful deletion.
36+
ActionDeleted string = "Deleted"
37+
// ActionValidating indicates validation is in progress.
38+
ActionValidating string = "Validating"
39+
// ActionValidated indicates successful validation.
40+
ActionValidated string = "Validated"
41+
// ActionWaiting indicates waiting for a condition.
42+
ActionWaiting string = "Waiting"
43+
// ActionProgressing indicates progression through a workflow.
44+
ActionProgressing string = "Progressing"
45+
// ActionFailed indicates a failed operation.
46+
ActionFailed string = "Failed"
47+
)

apis/event/v1beta1/event.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ type Event struct {
4646
// +required
4747
InvolvedObject corev1.ObjectReference `json:"involvedObject"`
4848

49+
// RelatedObject is an optional secondary object for more complex actions.
50+
// For simple events, this field may be left empty.
51+
// +optional
52+
RelatedObject corev1.ObjectReference `json:"relatedObject"`
53+
4954
// Severity type of this event (trace, info, error)
5055
// +kubebuilder:validation:Enum=trace;info;error
5156
// +required
@@ -66,6 +71,11 @@ type Event struct {
6671
// +required
6772
Reason string `json:"reason"`
6873

74+
// Action describes what action was taken/failed regarding the object.
75+
// Examples: "Starting", "Syncing", "Deleting".
76+
// +required
77+
Action string `json:"action"`
78+
6979
// Metadata of this event, e.g. apply change set.
7080
// +optional
7181
Metadata map[string]string `json:"metadata,omitempty"`

runtime/events/recorder.go

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import (
3333
corev1 "k8s.io/api/core/v1"
3434
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3535
"k8s.io/apimachinery/pkg/runtime"
36-
kuberecorder "k8s.io/client-go/tools/record"
36+
"k8s.io/client-go/tools/events"
3737
"k8s.io/client-go/tools/reference"
3838
ctrl "sigs.k8s.io/controller-runtime"
3939

@@ -48,14 +48,14 @@ import (
4848
//
4949
// import (
5050
// ...
51-
// kuberecorder "k8s.io/client-go/tools/record"
51+
// "k8s.io/client-go/tools/events"
5252
// ...
5353
// )
5454
//
5555
// type MyTypeReconciler {
5656
// client.Client
5757
// // ... etc.
58-
// kuberecorder.EventRecorder
58+
// events.EventRecorder
5959
// }
6060
//
6161
// Use NewRecorder to create a working Recorder.
@@ -70,7 +70,7 @@ type Recorder struct {
7070
Client *retryablehttp.Client
7171

7272
// EventRecorder is the Kubernetes event recorder.
73-
EventRecorder kuberecorder.EventRecorder
73+
EventRecorder events.EventRecorder
7474

7575
// Scheme to look up the recorded objects.
7676
Scheme *runtime.Scheme
@@ -79,7 +79,7 @@ type Recorder struct {
7979
Log logr.Logger
8080
}
8181

82-
var _ kuberecorder.EventRecorder = &Recorder{}
82+
var _ events.EventRecorder = &Recorder{}
8383

8484
// NewRecorder creates an event Recorder with a Kubernetes event recorder and an external event recorder based on the
8585
// given webhook. The recorder performs automatic retries for connection errors and 500-range response codes from the
@@ -101,7 +101,7 @@ func NewRecorder(mgr ctrl.Manager, log logr.Logger, webhook, reportingController
101101
Webhook: webhook,
102102
ReportingController: reportingController,
103103
Client: httpClient,
104-
EventRecorder: mgr.GetEventRecorderFor(reportingController),
104+
EventRecorder: mgr.GetEventRecorder(reportingController),
105105
Log: log,
106106
}, nil
107107
}
@@ -110,7 +110,7 @@ func NewRecorder(mgr ctrl.Manager, log logr.Logger, webhook, reportingController
110110
// given webhook. The recorder performs automatic retries for connection errors and 500-range response codes from the
111111
// external recorder.
112112
func NewRecorderForScheme(scheme *runtime.Scheme,
113-
eventRecorder kuberecorder.EventRecorder,
113+
eventRecorder events.EventRecorder,
114114
log logr.Logger, webhook, reportingController string) (*Recorder, error) {
115115
if webhook != "" {
116116
if _, err := url.Parse(webhook); err != nil {
@@ -148,21 +148,23 @@ func responseIsEventDuplicated(resp *http.Response) bool {
148148
}
149149

150150
// Event records an event in the webhook address.
151-
func (r *Recorder) Event(object runtime.Object, eventtype, reason, message string) {
152-
r.AnnotatedEventf(object, nil, eventtype, reason, "%s", message)
151+
func (r *Recorder) Event(object runtime.Object, related runtime.Object, eventtype, reason string, action string, message string) {
152+
r.AnnotatedEventf(object, related, nil, eventtype, reason, action, "%s", message)
153153
}
154154

155155
// Event records an event in the webhook address.
156-
func (r *Recorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) {
157-
r.AnnotatedEventf(object, nil, eventtype, reason, messageFmt, args...)
156+
func (r *Recorder) Eventf(object runtime.Object, related runtime.Object, eventtype, reason string, action string, messageFmt string, args ...interface{}) {
157+
r.AnnotatedEventf(object, related, nil, eventtype, reason, action, messageFmt, args...)
158158
}
159159

160160
// AnnotatedEventf constructs an event from the given information and performs a HTTP POST to the webhook address.
161161
// It also logs the event if debug logs are enabled in the logger.
162162
func (r *Recorder) AnnotatedEventf(
163163
object runtime.Object,
164+
related runtime.Object,
164165
inputAnnotations map[string]string,
165166
eventtype, reason string,
167+
action string,
166168
messageFmt string, args ...interface{}) {
167169

168170
ref, err := reference.GetReference(r.Scheme, object)
@@ -202,12 +204,12 @@ func (r *Recorder) AnnotatedEventf(
202204
// Do not send trace events to notification controller,
203205
// traces are persisted as Kubernetes events only as normal events.
204206
if severity == eventv1.EventSeverityTrace {
205-
r.EventRecorder.AnnotatedEventf(object, annotations, corev1.EventTypeNormal, reason, messageFmt, args...)
207+
r.EventRecorder.Eventf(object, related, corev1.EventTypeNormal, reason, action, messageFmt, args...)
206208
return
207209
}
208210

209211
// Forward the event to the Kubernetes recorder.
210-
r.EventRecorder.AnnotatedEventf(object, annotations, eventtype, reason, messageFmt, args...)
212+
r.EventRecorder.Eventf(object, related, eventtype, reason, action, messageFmt, args...)
211213

212214
// If no webhook address is provided, skip posting to event recorder
213215
// endpoint.
@@ -253,11 +255,18 @@ func (r *Recorder) AnnotatedEventf(
253255
Timestamp: metav1.Now(),
254256
Message: message,
255257
Reason: reason,
258+
Action: action,
256259
Metadata: annotations,
257260
ReportingController: r.ReportingController,
258261
ReportingInstance: hostname,
259262
}
260263

264+
// Add related object reference if provided (optional).
265+
relatedRef, err := reference.GetReference(r.Scheme, related)
266+
if err == nil {
267+
event.RelatedObject = *relatedRef
268+
}
269+
261270
body, err := json.Marshal(event)
262271
if err != nil {
263272
log.Error(err, "failed to marshal object into json")

runtime/events/recorder_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ func TestEventRecorder_AnnotatedEventf(t *testing.T) {
102102
require.Equal(t, "webapp", payload.InvolvedObject.Name)
103103
require.Equal(t, "gitops-system", payload.InvolvedObject.Namespace)
104104
require.Equal(t, "sync", payload.Reason)
105+
require.Equal(t, eventv1.ActionReconciling, payload.Action)
105106
require.Equal(t, "sync object", payload.Message)
106107

107108
for k, v := range tt.expectedMetadata {
@@ -117,11 +118,11 @@ func TestEventRecorder_AnnotatedEventf(t *testing.T) {
117118

118119
const msg = "sync object"
119120

120-
eventRecorder.AnnotatedEventf(obj, tt.inputAnnotations, corev1.EventTypeNormal, "sync", "%s", msg)
121+
eventRecorder.AnnotatedEventf(obj, nil, tt.inputAnnotations, corev1.EventTypeNormal, "sync", eventv1.ActionReconciling, "%s", msg)
121122
require.Equal(t, 1, requestCount)
122123

123124
// When a trace event is sent, it's dropped, no new request.
124-
eventRecorder.AnnotatedEventf(obj, tt.inputAnnotations, eventv1.EventTypeTrace, "sync", "%s", msg)
125+
eventRecorder.AnnotatedEventf(obj, nil, tt.inputAnnotations, eventv1.EventTypeTrace, "sync", eventv1.ActionReconciling, "%s", msg)
125126
require.Equal(t, 1, requestCount)
126127
})
127128
}
@@ -150,7 +151,7 @@ func TestEventRecorder_AnnotatedEventf_Retry(t *testing.T) {
150151
obj.Namespace = "gitops-system"
151152
obj.Name = "webapp"
152153

153-
eventRecorder.AnnotatedEventf(obj, nil, corev1.EventTypeNormal, "sync", "sync %s", obj.Name)
154+
eventRecorder.AnnotatedEventf(obj, nil, nil, corev1.EventTypeNormal, "sync", eventv1.ActionReconciling, "sync %s", obj.Name)
154155
require.True(t, requestCount > 1)
155156
}
156157

@@ -177,7 +178,7 @@ func TestEventRecorder_AnnotatedEventf_RateLimited(t *testing.T) {
177178
obj.Namespace = "gitops-system"
178179
obj.Name = "webapp"
179180

180-
eventRecorder.AnnotatedEventf(obj, nil, corev1.EventTypeNormal, "sync", "sync %s", obj.Name)
181+
eventRecorder.AnnotatedEventf(obj, nil, nil, corev1.EventTypeNormal, "sync", eventv1.ActionReconciling, "sync %s", obj.Name)
181182
require.Equal(t, 1, requestCount)
182183
}
183184

runtime/go.mod

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ require (
2828
github.com/spf13/pflag v1.0.10
2929
github.com/stretchr/testify v1.11.1
3030
go.uber.org/zap v1.27.1
31-
golang.org/x/net v0.49.0
32-
k8s.io/api v0.35.1
33-
k8s.io/apimachinery v0.35.1
34-
k8s.io/client-go v0.35.1
31+
golang.org/x/net v0.51.0
32+
k8s.io/api v0.35.2
33+
k8s.io/apimachinery v0.35.2
34+
k8s.io/client-go v0.35.2
3535
k8s.io/component-base v0.35.1
36-
k8s.io/klog/v2 v2.130.1
36+
k8s.io/klog/v2 v2.140.0
3737
sigs.k8s.io/controller-runtime v0.23.1
3838
sigs.k8s.io/yaml v1.6.0
3939
)
@@ -51,25 +51,34 @@ require (
5151
github.com/cespare/xxhash/v2 v2.3.0 // indirect
5252
github.com/chai2010/gettext-go v1.0.2 // indirect
5353
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
54-
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
54+
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
5555
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
5656
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
5757
github.com/fsnotify/fsnotify v1.9.0 // indirect
5858
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
5959
github.com/go-errors/errors v1.5.1 // indirect
60-
github.com/go-openapi/jsonpointer v0.21.1 // indirect
61-
github.com/go-openapi/jsonreference v0.21.0 // indirect
62-
github.com/go-openapi/swag v0.23.1 // indirect
60+
github.com/go-openapi/jsonpointer v0.22.5 // indirect
61+
github.com/go-openapi/jsonreference v0.21.5 // indirect
62+
github.com/go-openapi/swag v0.25.5 // indirect
63+
github.com/go-openapi/swag/cmdutils v0.25.5 // indirect
64+
github.com/go-openapi/swag/conv v0.25.5 // indirect
65+
github.com/go-openapi/swag/fileutils v0.25.5 // indirect
66+
github.com/go-openapi/swag/jsonname v0.25.5 // indirect
67+
github.com/go-openapi/swag/jsonutils v0.25.5 // indirect
68+
github.com/go-openapi/swag/loading v0.25.5 // indirect
69+
github.com/go-openapi/swag/mangling v0.25.5 // indirect
70+
github.com/go-openapi/swag/netutils v0.25.5 // indirect
71+
github.com/go-openapi/swag/stringutils v0.25.5 // indirect
72+
github.com/go-openapi/swag/typeutils v0.25.5 // indirect
73+
github.com/go-openapi/swag/yamlutils v0.25.5 // indirect
6374
github.com/google/btree v1.1.3 // indirect
64-
github.com/google/gnostic-models v0.7.0 // indirect
75+
github.com/google/gnostic-models v0.7.1 // indirect
6576
github.com/google/uuid v1.6.0 // indirect
6677
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
6778
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
6879
github.com/inconshreveable/mousetrap v1.1.0 // indirect
69-
github.com/josharian/intern v1.0.0 // indirect
7080
github.com/json-iterator/go v1.1.12 // indirect
7181
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
72-
github.com/mailru/easyjson v0.9.0 // indirect
7382
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
7483
github.com/moby/term v0.5.0 // indirect
7584
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@@ -87,30 +96,30 @@ require (
8796
github.com/x448/float16 v0.8.4 // indirect
8897
github.com/xlab/treeprint v1.2.0 // indirect
8998
go.uber.org/multierr v1.11.0 // indirect
90-
go.yaml.in/yaml/v2 v2.4.3 // indirect
99+
go.yaml.in/yaml/v2 v2.4.4 // indirect
91100
go.yaml.in/yaml/v3 v3.0.4 // indirect
92101
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
93-
golang.org/x/oauth2 v0.34.0 // indirect
102+
golang.org/x/oauth2 v0.36.0 // indirect
94103
golang.org/x/sync v0.19.0 // indirect
95-
golang.org/x/sys v0.40.0 // indirect
96-
golang.org/x/term v0.39.0 // indirect
97-
golang.org/x/text v0.33.0 // indirect
98-
golang.org/x/time v0.14.0 // indirect
104+
golang.org/x/sys v0.42.0 // indirect
105+
golang.org/x/term v0.40.0 // indirect
106+
golang.org/x/text v0.34.0 // indirect
107+
golang.org/x/time v0.15.0 // indirect
99108
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
100109
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
101110
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
102-
google.golang.org/protobuf v1.36.8 // indirect
111+
google.golang.org/protobuf v1.36.11 // indirect
103112
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
104113
gopkg.in/inf.v0 v0.9.1 // indirect
105114
gopkg.in/yaml.v3 v3.0.1 // indirect
106115
k8s.io/apiextensions-apiserver v0.35.1 // indirect
107116
k8s.io/cli-runtime v0.35.1 // indirect
108-
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect
117+
k8s.io/kube-openapi v0.0.0-20260304202019-5b3e3fdb0acf // indirect
109118
k8s.io/kubectl v0.35.1 // indirect
110-
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect
119+
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect
111120
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
112121
sigs.k8s.io/kustomize/api v0.21.1 // indirect
113122
sigs.k8s.io/kustomize/kyaml v0.21.1 // indirect
114123
sigs.k8s.io/randfill v1.0.0 // indirect
115-
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect
124+
sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect
116125
)

0 commit comments

Comments
 (0)