Skip to content

Commit 0f390a9

Browse files
authored
Merge pull request #3450 from Sajiyah-Salat/raising-events
📖 Raising event doc page created
2 parents e24af48 + 9c3575e commit 0f390a9

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

docs/book/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080

8181
- [Generating CRDs](./reference/generating-crd.md)
8282
- [Using Finalizers](./reference/using-finalizers.md)
83+
- [Raising Events](./reference/raising-events.md)
8384
- [Watching Resources](./reference/watching-resources.md)
8485
- [Resources Managed by the Operator](./reference/watching-resources/operator-managed.md)
8586
- [Externally Managed Resources](./reference/watching-resources/externally-managed.md)
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Creating Events
2+
3+
It is often useful to publish *Event* objects from the controller Reconcile function as they allow users or any automated processes to see what is going on with a particular object and respond to them.
4+
5+
Recent Events for an object can be viewed by running `$ kubectl describe <resource kind> <resource name>`. Also, they can be checked by running `$ kubectl get events`.
6+
7+
<aside class="warning">
8+
<h1>Events should be raised in certain circumstances only</h1>
9+
10+
Be aware that it is **not** recommended to emit Events for all operations. If authors raise too many events, it brings bad UX experiences for those consuming the solutions on the cluster, and they may find it difficult to filter an actionable event from the clutter. For more information, please take a look at the [Kubernetes APIs convention][Events].
11+
12+
</aside>
13+
14+
## Writing Events
15+
16+
Anatomy of an Event:
17+
18+
```go
19+
Event(object runtime.Object, eventtype, reason, message string)
20+
```
21+
22+
- `object` is the object this event is about.
23+
- `eventtype` is this event type, and is either *Normal* or *Warning*. ([More info][Event-Example])
24+
- `reason` is the reason this event is generated. It should be short and unique with `UpperCamelCase` format. The value could appear in *switch* statements by automation. ([More info][Reason-Example])
25+
- `message` is intended to be consumed by humans. ([More info][Message-Example])
26+
27+
28+
29+
<aside class="note">
30+
<h1>Example Usage</h1>
31+
32+
Following is an example of a code implementation that raises an Event.
33+
34+
```go
35+
// The following implementation will raise an event
36+
r.Recorder.Event(cr, "Warning", "Deleting",
37+
fmt.Sprintf("Custom Resource %s is being deleted from the namespace %s",
38+
cr.Name,
39+
cr.Namespace))
40+
```
41+
42+
</aside>
43+
44+
## How to be able to raise Events?
45+
46+
Following are the steps with examples to help you raise events in your controller's reconciliations.
47+
Events are published from a Controller using an [EventRecorder]`type CorrelatorOptions struct`,
48+
which can be created for a Controller by calling `GetRecorder(name string)` on a Manager. See that we will change the implementation scaffolded in `cmd/main.go`:
49+
50+
```go
51+
if err = (&controller.MyKindReconciler{
52+
Client: mgr.GetClient(),
53+
Scheme: mgr.GetScheme(),
54+
// Note that we added the following line:
55+
Recorder: mgr.GetEventRecorderFor("mykind-controller"),
56+
}).SetupWithManager(mgr); err != nil {
57+
setupLog.Error(err, "unable to create controller", "controller", "MyKind")
58+
os.Exit(1)
59+
}
60+
```
61+
62+
### Allowing usage of EventRecorder on the Controller
63+
To raise an event, you must have access to `record.EventRecorder` in the Controller. Therefore, firstly let's update the controller implementation:
64+
```go
65+
import (
66+
...
67+
"k8s.io/client-go/tools/record"
68+
...
69+
)
70+
// MyKindReconciler reconciles a MyKind object
71+
type MyKindReconciler struct {
72+
client.Client
73+
Scheme *runtime.Scheme
74+
// See that we added the following code to allow us to pass the record.EventRecorder
75+
Recorder record.EventRecorder
76+
}
77+
### Passing the EventRecorder to the Controller
78+
Events are published from a Controller using an [EventRecorder]`type CorrelatorOptions struct`,
79+
which can be created for a Controller by calling `GetRecorder(name string)` on a Manager. See that we will change the implementation scaffolded in `cmd/main.go`:
80+
```go
81+
if err = (&controller.MyKindReconciler{
82+
Client: mgr.GetClient(),
83+
Scheme: mgr.GetScheme(),
84+
// Note that we added the following line:
85+
Recorder: mgr.GetEventRecorderFor("mykind-controller"),
86+
}).SetupWithManager(mgr); err != nil {
87+
setupLog.Error(err, "unable to create controller", "controller", "MyKind")
88+
os.Exit(1)
89+
}
90+
```
91+
### Granting the required permissions
92+
You must also grant the RBAC rules permissions to allow your project to create Events. Therefore, ensure that you add the [RBAC][rbac-markers] into your controller:
93+
```go
94+
...
95+
//+kubebuilder:rbac:groups=core,resources=events,verbs=create;patch
96+
...
97+
func (r *MyKindReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
98+
```
99+
And then, run `$ make manifests` to update the rules under `config/rbac/rule.yaml`.
100+
101+
[Events]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#events
102+
[Event-Example]: https://github.com/kubernetes/api/blob/6c11c9e4685cc62e4ddc8d4aaa824c46150c9148/core/v1/types.go#L6019-L6024
103+
[Reason-Example]: https://github.com/kubernetes/api/blob/6c11c9e4685cc62e4ddc8d4aaa824c46150c9148/core/v1/types.go#L6048
104+
[Message-Example]: https://github.com/kubernetes/api/blob/6c11c9e4685cc62e4ddc8d4aaa824c46150c9148/core/v1/types.go#L6053
105+
[rbac-markers]: ./markers/rbac.md

0 commit comments

Comments
 (0)