Skip to content

Commit ae66113

Browse files
hagaibarelHagai Barel
authored and
Hagai Barel
committed
📖 update create events section
1 parent ed7c770 commit ae66113

File tree

1 file changed

+123
-6
lines changed

1 file changed

+123
-6
lines changed
Lines changed: 123 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,143 @@
11
# Creating Events
22

3-
It is often useful to publish *Event* objects from the controller Reconcile function. Events
4-
allow users to see what is going on with a particular object, and allow automated processes
5-
to see and respond to them.
3+
It is often useful to publish *Event* objects from the controller Reconcile function.
4+
5+
Events allow users to see what is going on with a particular object, and allow automated processes to see and respond to them.
66

77
{% panel style="success", title="Getting Events" %}
8-
Recent Events for an object may be viewed by running `kubectl describe`
8+
Recent Events for an object can be viewed by running `kubectl describe`
99
{% endpanel %}
1010

1111
{% method %}
1212

1313
Events are published from a Controller using an [EventRecorder](https://github.com/kubernetes/client-go/blob/master/tools/record/event.go#L56),
1414
which can be created for a Controller by calling `GetRecorder(name string)` on a Manager.
1515

16+
`Name` should be identifiable and descriptive as it will appear in the `From` column of `kubectl describe` command.
17+
18+
{% sample lang="go" %}
19+
```go
20+
// Annotation for generating RBAC role for writing Events
21+
// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch
22+
```
23+
24+
```go
25+
// ReconcileContainerSet reconciles a ContainerSet object
26+
type ReconcileContainerSet struct {
27+
client.Client
28+
scheme *runtime.Scheme
29+
recorder record.EventRecorder
30+
}
31+
```
32+
```go
33+
// newReconciler returns a new reconcile.Reconciler
34+
func newReconciler(mgr manager.Manager) reconcile.Reconciler {
35+
return &ReconcileContainerSet{
36+
Client: mgr.GetClient(),
37+
scheme: mgr.GetScheme(),
38+
recorder: mgr.GetRecorder("containerset-controller"),
39+
}
40+
}
41+
```
42+
{% endmethod %}
43+
44+
{% method %}
45+
46+
## Writing Events
47+
48+
Anatomy of an Event:
49+
1650
```go
1751
Event(object runtime.Object, eventtype, reason, message string)
1852
```
1953

2054
- `object` is the object this event is about.
2155
- `eventtype` is the type of this event, and is either *Normal* or *Warning*.
22-
- `reason` is the reason this event is generated. It should be short and unique with
23-
`UpperCamelCase` format. The value could appear in *switch* statements by automation.
56+
- `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.
2457
- `message` is intended to be consumed by humans.
2558

59+
60+
Building on the example introduced in [Controller Example](../basics/simple_controller.md), we can add Events to our reconcile logic using `recorder` as our `EventRecorder`
61+
62+
{% sample lang="go" %}
63+
```go
64+
var _ reconcile.Reconciler = &ContainerSetController{}
65+
66+
func (r *ReconcileContainerSet) Reconcile(request reconcile.Request) (reconcile.Result, error) {
67+
instance := &workloadsv1beta1.ContainerSet{}
68+
err := r.Get(context.TODO(), request.NamespacedName, instance)
69+
if err != nil {
70+
if errors.IsNotFound(err) {
71+
// Object not found, return. Created objects are automatically garbage collected.
72+
// For additional cleanup logic use finalizers.
73+
return reconcile.Result{}, nil
74+
}
75+
// Error reading the object - requeue the request.
76+
return reconcile.Result{}, err
77+
}
78+
79+
// TODO(user): Change this to be the object type created by your controller
80+
// Define the desired Deployment object
81+
deploy := &appsv1.Deployment{
82+
ObjectMeta: metav1.ObjectMeta{
83+
Name: instance.Name + "-deployment",
84+
Namespace: instance.Namespace,
85+
},
86+
Spec: appsv1.DeploymentSpec{
87+
Selector: &metav1.LabelSelector{
88+
MatchLabels: map[string]string{"deployment": instance.Name + "-deployment"},
89+
},
90+
Replicas: &instance.Spec.Replicas,
91+
Template: corev1.PodTemplateSpec{
92+
ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": instance.Name + "-deployment"}},
93+
Spec: corev1.PodSpec{
94+
Containers: []corev1.Container{
95+
{
96+
Name: instance.Name,
97+
Image: instance.Spec.Image,
98+
},
99+
},
100+
},
101+
},
102+
},
103+
}
104+
105+
if err := controllerutil.SetControllerReference(instance, deploy, r.scheme); err != nil {
106+
return reconcile.Result{}, err
107+
}
108+
109+
// TODO(user): Change this for the object type created by your controller
110+
// Check if the Deployment already exists
111+
found := &appsv1.Deployment{}
112+
err = r.Get(context.TODO(), types.NamespacedName{Name: deploy.Name, Namespace: deploy.Namespace}, found)
113+
if err != nil && errors.IsNotFound(err) {
114+
log.Printf("Creating Deployment %s/%s\n", deploy.Namespace, deploy.Name)
115+
err = r.Create(context.TODO(), deploy)
116+
if err != nil {
117+
return reconcile.Result{}, err
118+
}
119+
// Write an event to the ContainerSet instance with the namespace and name of the
120+
// created deployment
121+
r.recorder.Event(instance, "Normal", "Created", fmt.Sprintf("Created deployment %s/%s", deploy.Namespace, deploy.Name))
122+
} else if err != nil {
123+
return reconcile.Result{}, err
124+
}
125+
126+
// TODO(user): Change this for the object type created by your controller
127+
// Update the found object and write the result back if there are any changes
128+
if !reflect.DeepEqual(deploy.Spec, found.Spec) {
129+
found.Spec = deploy.Spec
130+
log.Printf("Updating Deployment %s/%s\n", deploy.Namespace, deploy.Name)
131+
err = r.Update(context.TODO(), found)
132+
if err != nil {
133+
return reconcile.Result{}, err
134+
}
135+
// Write an event to the ContainerSet instance with the namespace and name of the
136+
// updated deployment
137+
r.recorder.Event(instance, "Normal", "Updated", fmt.Sprintf("Updated deployment %s/%s", deploy.Namespace, deploy.Name))
138+
}
139+
return reconcile.Result{}, nil
140+
}
141+
```
142+
26143
{% endmethod %}

0 commit comments

Comments
 (0)