Promote new Event API to v1

This commit is contained in:
Chelsey Chen
2020-06-01 11:03:13 -04:00
parent 1cbda2493d
commit 75612c1746
23 changed files with 1458 additions and 41 deletions

View File

@@ -18,9 +18,14 @@ package validation
import (
"fmt"
"reflect"
"time"
"k8s.io/api/core/v1"
eventsv1beta1 "k8s.io/api/events/v1beta1"
apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kubernetes/pkg/apis/core"
@@ -33,8 +38,88 @@ const (
NoteLengthLimit = 1024
)
// ValidateEvent makes sure that the event makes sense.
func ValidateEvent(event *core.Event) field.ErrorList {
func ValidateEventCreate(event *core.Event, requestVersion schema.GroupVersion) field.ErrorList {
// Make sure events always pass legacy validation.
allErrs := legacyValidateEvent(event)
if requestVersion == v1.SchemeGroupVersion || requestVersion == eventsv1beta1.SchemeGroupVersion {
// No further validation for backwards compatibility.
return allErrs
}
// Strict validation applies to creation via events.k8s.io/v1 API and newer.
allErrs = append(allErrs, ValidateObjectMeta(&event.ObjectMeta, true, apimachineryvalidation.NameIsDNSSubdomain, field.NewPath("metadata"))...)
allErrs = append(allErrs, validateV1EventSeries(event)...)
zeroTime := time.Time{}
if event.EventTime.Time == zeroTime {
allErrs = append(allErrs, field.Required(field.NewPath("eventTime"), ""))
}
if event.Type != v1.EventTypeNormal && event.Type != v1.EventTypeWarning {
allErrs = append(allErrs, field.Invalid(field.NewPath("type"), "", fmt.Sprintf("has invalid value: %v", event.Type)))
}
if event.FirstTimestamp.Time != zeroTime {
allErrs = append(allErrs, field.Invalid(field.NewPath("firstTimestamp"), "", "needs to be unset"))
}
if event.LastTimestamp.Time != zeroTime {
allErrs = append(allErrs, field.Invalid(field.NewPath("lastTimestamp"), "", "needs to be unset"))
}
if event.Count != 0 {
allErrs = append(allErrs, field.Invalid(field.NewPath("count"), "", "needs to be unset"))
}
if event.Source.Component != "" || event.Source.Host != "" {
allErrs = append(allErrs, field.Invalid(field.NewPath("source"), "", "needs to be unset"))
}
return allErrs
}
func ValidateEventUpdate(newEvent, oldEvent *core.Event, requestVersion schema.GroupVersion) field.ErrorList {
// Make sure the new event always passes legacy validation.
allErrs := legacyValidateEvent(newEvent)
if requestVersion == v1.SchemeGroupVersion || requestVersion == eventsv1beta1.SchemeGroupVersion {
// No further validation for backwards compatibility.
return allErrs
}
// Strict validation applies to update via events.k8s.io/v1 API and newer.
allErrs = append(allErrs, ValidateObjectMetaUpdate(&newEvent.ObjectMeta, &oldEvent.ObjectMeta, field.NewPath("metadata"))...)
// if the series was modified, validate the new data
if !reflect.DeepEqual(newEvent.Series, oldEvent.Series) {
allErrs = append(allErrs, validateV1EventSeries(newEvent)...)
}
allErrs = append(allErrs, ValidateImmutableField(newEvent.InvolvedObject, oldEvent.InvolvedObject, field.NewPath("involvedObject"))...)
allErrs = append(allErrs, ValidateImmutableField(newEvent.Reason, oldEvent.Reason, field.NewPath("reason"))...)
allErrs = append(allErrs, ValidateImmutableField(newEvent.Message, oldEvent.Message, field.NewPath("message"))...)
allErrs = append(allErrs, ValidateImmutableField(newEvent.Source, oldEvent.Source, field.NewPath("source"))...)
allErrs = append(allErrs, ValidateImmutableField(newEvent.FirstTimestamp, oldEvent.FirstTimestamp, field.NewPath("firstTimestamp"))...)
allErrs = append(allErrs, ValidateImmutableField(newEvent.LastTimestamp, oldEvent.LastTimestamp, field.NewPath("lastTimestamp"))...)
allErrs = append(allErrs, ValidateImmutableField(newEvent.Count, oldEvent.Count, field.NewPath("count"))...)
allErrs = append(allErrs, ValidateImmutableField(newEvent.Reason, oldEvent.Reason, field.NewPath("reason"))...)
allErrs = append(allErrs, ValidateImmutableField(newEvent.Type, oldEvent.Type, field.NewPath("type"))...)
allErrs = append(allErrs, ValidateImmutableField(newEvent.EventTime, oldEvent.EventTime, field.NewPath("eventTime"))...)
allErrs = append(allErrs, ValidateImmutableField(newEvent.Action, oldEvent.Action, field.NewPath("action"))...)
allErrs = append(allErrs, ValidateImmutableField(newEvent.Related, oldEvent.Related, field.NewPath("related"))...)
allErrs = append(allErrs, ValidateImmutableField(newEvent.ReportingController, oldEvent.ReportingController, field.NewPath("reportingController"))...)
allErrs = append(allErrs, ValidateImmutableField(newEvent.ReportingInstance, oldEvent.ReportingInstance, field.NewPath("reportingInstance"))...)
return allErrs
}
func validateV1EventSeries(event *core.Event) field.ErrorList {
allErrs := field.ErrorList{}
zeroTime := time.Time{}
if event.Series != nil {
if event.Series.Count < 2 {
allErrs = append(allErrs, field.Invalid(field.NewPath("series.count"), "", fmt.Sprintf("should be at least 2")))
}
if event.Series.LastObservedTime.Time == zeroTime {
allErrs = append(allErrs, field.Required(field.NewPath("series.lastObservedTime"), ""))
}
}
return allErrs
}
// legacyValidateEvent makes sure that the event makes sense.
func legacyValidateEvent(event *core.Event) field.ErrorList {
allErrs := field.ErrorList{}
// Because go
zeroTime := time.Time{}

View File

@@ -20,11 +20,14 @@ import (
"testing"
"time"
"k8s.io/api/core/v1"
eventsv1 "k8s.io/api/events/v1"
eventsv1beta1 "k8s.io/api/events/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/core"
)
func TestValidateEvent(t *testing.T) {
func TestValidateEventForCoreV1Events(t *testing.T) {
table := []struct {
*core.Event
valid bool
@@ -214,13 +217,18 @@ func TestValidateEvent(t *testing.T) {
}
for _, item := range table {
if e, a := item.valid, len(ValidateEvent(item.Event)) == 0; e != a {
t.Errorf("%v: expected %v, got %v: %v", item.Event.Name, e, a, ValidateEvent(item.Event))
createErrs := ValidateEventCreate(item.Event, v1.SchemeGroupVersion)
if e, a := item.valid, len(createErrs) == 0; e != a {
t.Errorf("%v: expected %v, got %v: %v", item.Event.Name, e, a, createErrs)
}
updateErrs := ValidateEventUpdate(item.Event, &core.Event{}, v1.SchemeGroupVersion)
if e, a := item.valid, len(updateErrs) == 0; e != a {
t.Errorf("%v: expected %v, got %v: %v", item.Event.Name, e, a, updateErrs)
}
}
}
func TestValidateNewEvent(t *testing.T) {
func TestValidateEventForNewV1beta1Events(t *testing.T) {
someTime := metav1.MicroTime{Time: time.Unix(1505828956, 0)}
table := []struct {
*core.Event
@@ -384,8 +392,923 @@ zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz`,
}
for _, item := range table {
if e, a := item.valid, len(ValidateEvent(item.Event)) == 0; e != a {
t.Errorf("%v: expected %v, got %v: %v", item.msg, e, a, ValidateEvent(item.Event))
createErrs := ValidateEventCreate(item.Event, eventsv1beta1.SchemeGroupVersion)
if e, a := item.valid, len(createErrs) == 0; e != a {
t.Errorf("%v: expected %v, got %v: %v", item.msg, e, a, createErrs)
}
updateErrs := ValidateEventUpdate(item.Event, &core.Event{}, eventsv1beta1.SchemeGroupVersion)
if e, a := item.valid, len(updateErrs) == 0; e != a {
t.Errorf("%v: expected %v, got %v: %v", item.msg, e, a, updateErrs)
}
}
}
func TestValidateEventCreateForNewV1Events(t *testing.T) {
someTime := metav1.MicroTime{Time: time.Unix(1505828956, 0)}
table := []struct {
*core.Event
valid bool
msg string
}{
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Because",
Type: "Normal",
},
valid: true,
msg: "valid new event",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Namespace: metav1.NamespaceSystem,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Reason: "Because",
},
valid: false,
msg: "missing name in objectMeta",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Reason: "Because",
},
valid: false,
msg: "missing namespace in objectMeta",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceDefault,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
},
valid: false,
msg: "missing EventTime",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "my-contr@ller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Because",
},
valid: false,
msg: "not qualified reportingController",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
Action: "Do",
Reason: "Because",
},
valid: false,
msg: "too long reporting instance",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
},
valid: false,
msg: "missing reason",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Reason: "Because",
},
valid: false,
msg: "missing action",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Because",
Message: `zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz`,
},
valid: false,
msg: "too long message",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Because",
Type: "invalid-type",
},
valid: false,
msg: "invalid type",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Because",
Type: "Normal",
FirstTimestamp: metav1.Time{Time: time.Unix(1505828956, 0)},
},
valid: false,
msg: "non-empty firstTimestamp",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Because",
Type: "Normal",
LastTimestamp: metav1.Time{Time: time.Unix(1505828956, 0)},
},
valid: false,
msg: "non-empty lastTimestamp",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Because",
Type: "Normal",
Count: 123,
},
valid: false,
msg: "non-empty count",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Because",
Type: "Normal",
Source: core.EventSource{
Host: "host",
},
},
valid: false,
msg: "non-empty source",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Because",
Type: "Normal",
Series: &core.EventSeries{
Count: 0,
LastObservedTime: someTime,
},
},
valid: false,
msg: "non-nil series with cound < 2",
},
{
Event: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Because",
Type: "Normal",
Series: &core.EventSeries{
Count: 2,
},
},
valid: false,
msg: "non-nil series with empty lastObservedTime",
},
}
for _, item := range table {
createErrs := ValidateEventCreate(item.Event, eventsv1.SchemeGroupVersion)
if e, a := item.valid, len(createErrs) == 0; e != a {
t.Errorf("%v: expected %v, got %v: %v", item.msg, e, a, createErrs)
}
}
}
func TestValidateEventUpdateForNewV1Events(t *testing.T) {
someTime := metav1.MicroTime{Time: time.Unix(1505828956, 0)}
table := []struct {
newEvent *core.Event
oldEvent *core.Event
valid bool
msg string
}{
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "2",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v2",
Kind: "Node",
},
Series: &core.EventSeries{
Count: 2,
LastObservedTime: someTime,
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "2",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v2",
Kind: "Node",
},
Series: &core.EventSeries{
Count: 1,
LastObservedTime: someTime,
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
valid: true,
msg: "valid new updated event",
},
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v2",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
valid: false,
msg: "forbidden updates to involvedObject",
},
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees-new",
Type: "Normal",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
valid: false,
msg: "forbidden updates to reason",
},
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
Message: "new-message",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
Message: "message",
},
valid: false,
msg: "forbidden updates to message",
},
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
Source: core.EventSource{
Host: "host",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
valid: false,
msg: "forbidden updates to source",
},
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
FirstTimestamp: metav1.Time{Time: time.Unix(1505828956, 0)},
},
valid: false,
msg: "forbidden updates to firstTimestamp",
},
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
LastTimestamp: metav1.Time{Time: time.Unix(1505828956, 0)},
},
valid: false,
msg: "forbidden updates to lastTimestamp",
},
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
Count: 2,
},
valid: false,
msg: "forbidden updates to count",
},
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Warning",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
valid: false,
msg: "forbidden updates to type",
},
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: metav1.MicroTime{Time: time.Unix(1505828999, 0)},
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
valid: false,
msg: "forbidden updates to eventTime",
},
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Undo",
Reason: "Yeees",
Type: "Normal",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
valid: false,
msg: "forbidden updates to action",
},
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
Related: &core.ObjectReference{
APIVersion: "v1",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
valid: false,
msg: "forbidden updates to related",
},
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller/new",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
valid: false,
msg: "forbidden updates to reportingController",
},
{
newEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz-new",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
oldEvent: &core.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: metav1.NamespaceSystem,
ResourceVersion: "1",
},
InvolvedObject: core.ObjectReference{
APIVersion: "v1",
Kind: "Node",
},
EventTime: someTime,
ReportingController: "k8s.io/my-controller",
ReportingInstance: "node-xyz",
Action: "Do",
Reason: "Yeees",
Type: "Normal",
},
valid: false,
msg: "forbidden updates to reportingInstance",
},
}
for _, item := range table {
updateErrs := ValidateEventUpdate(item.newEvent, item.oldEvent, eventsv1.SchemeGroupVersion)
if e, a := item.valid, len(updateErrs) == 0; e != a {
t.Errorf("%v: expected %v, got %v: %v", item.msg, e, a, updateErrs)
}
}
}