events: fix EventSeries starting count discrepancy

The kube-apiserver validation expects the Count of an EventSeries to be
at least 2, otherwise it rejects the Event. There was is discrepancy
between the client and the server since the client was iniatizing an
EventSeries to a count of 1.

According to the original KEP, the first event emitted should have an
EventSeries set to nil and the second isomorphic event should have an
EventSeries with a count of 2. Thus, we should matcht the behavior
define by the KEP and update the client.

Also, as an effort to make the old clients compatible with the servers,
we should allow Events with an EventSeries count of 1 to prevent any
unexpected rejections.

Signed-off-by: Damien Grisonnet <dgrisonn@redhat.com>
This commit is contained in:
Damien Grisonnet 2022-09-08 23:50:41 +02:00
parent 67bde9a102
commit d00364902b
3 changed files with 62 additions and 2 deletions

View File

@ -181,7 +181,7 @@ func (e *eventBroadcasterImpl) recordToSink(event *eventsv1.Event, clock clock.C
return nil
}
isomorphicEvent.Series = &eventsv1.EventSeries{
Count: 1,
Count: 2,
LastObservedTime: metav1.MicroTime{Time: clock.Now()},
}
return isomorphicEvent

View File

@ -106,7 +106,7 @@ func TestEventSeriesf(t *testing.T) {
nonIsomorphicEvent := expectedEvent.DeepCopy()
nonIsomorphicEvent.Action = "stopped"
expectedEvent.Series = &eventsv1.EventSeries{Count: 1}
expectedEvent.Series = &eventsv1.EventSeries{Count: 2}
table := []struct {
regarding k8sruntime.Object
related k8sruntime.Object

View File

@ -18,6 +18,7 @@ package events
import (
"context"
"fmt"
"testing"
"time"
@ -96,3 +97,62 @@ func TestEventCompatibility(t *testing.T) {
t.Fatalf("unexpected err: %v", err)
}
}
func TestEventSeries(t *testing.T) {
result := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins", "ServiceAccount"}, framework.SharedEtcd())
defer result.TearDownFn()
client := clientset.NewForConfigOrDie(result.ClientConfig)
testPod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
Namespace: "default",
UID: "bar",
},
}
regarding, err := ref.GetReference(scheme.Scheme, testPod)
if err != nil {
t.Fatal(err)
}
related, err := ref.GetPartialReference(scheme.Scheme, testPod, ".spec.containers[0]")
if err != nil {
t.Fatal(err)
}
stopCh := make(chan struct{})
defer close(stopCh)
broadcaster := events.NewBroadcaster(&events.EventSinkImpl{Interface: client.EventsV1()})
defer broadcaster.Shutdown()
recorder := broadcaster.NewRecorder(scheme.Scheme, "k8s.io/kube-scheduler")
broadcaster.StartRecordingToSink(stopCh)
recorder.Eventf(regarding, related, v1.EventTypeNormal, "memoryPressure", "killed", "memory pressure")
recorder.Eventf(regarding, related, v1.EventTypeNormal, "memoryPressure", "killed", "memory pressure")
err = wait.PollImmediate(100*time.Millisecond, 20*time.Second, func() (done bool, err error) {
events, err := client.EventsV1().Events("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
return false, err
}
if len(events.Items) != 1 {
return false, nil
}
if events.Items[0].Series == nil {
return false, nil
}
if events.Items[0].Series.Count != 2 {
return false, fmt.Errorf("expected EventSeries to have a starting count of 2, got: %d", events.Items[0].Series.Count)
}
return true, nil
})
if err != nil {
t.Fatalf("error waiting for an Event with a non nil Series to be created: %v", err)
}
}