@@ -18,9 +18,14 @@ package validation
18
18
19
19
import (
20
20
"fmt"
21
+ "reflect"
21
22
"time"
22
23
24
+ "k8s.io/api/core/v1"
25
+ eventsv1beta1 "k8s.io/api/events/v1beta1"
26
+ apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
23
27
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28
+ "k8s.io/apimachinery/pkg/runtime/schema"
24
29
"k8s.io/apimachinery/pkg/util/validation"
25
30
"k8s.io/apimachinery/pkg/util/validation/field"
26
31
"k8s.io/kubernetes/pkg/apis/core"
@@ -33,8 +38,88 @@ const (
33
38
NoteLengthLimit = 1024
34
39
)
35
40
36
- // ValidateEvent makes sure that the event makes sense.
37
- func ValidateEvent (event * core.Event ) field.ErrorList {
41
+ func ValidateEventCreate (event * core.Event , requestVersion schema.GroupVersion ) field.ErrorList {
42
+ // Make sure events always pass legacy validation.
43
+ allErrs := legacyValidateEvent (event )
44
+ if requestVersion == v1 .SchemeGroupVersion || requestVersion == eventsv1beta1 .SchemeGroupVersion {
45
+ // No further validation for backwards compatibility.
46
+ return allErrs
47
+ }
48
+
49
+ // Strict validation applies to creation via events.k8s.io/v1 API and newer.
50
+ allErrs = append (allErrs , ValidateObjectMeta (& event .ObjectMeta , true , apimachineryvalidation .NameIsDNSSubdomain , field .NewPath ("metadata" ))... )
51
+ allErrs = append (allErrs , validateV1EventSeries (event )... )
52
+ zeroTime := time.Time {}
53
+ if event .EventTime .Time == zeroTime {
54
+ allErrs = append (allErrs , field .Required (field .NewPath ("eventTime" ), "" ))
55
+ }
56
+ if event .Type != v1 .EventTypeNormal && event .Type != v1 .EventTypeWarning {
57
+ allErrs = append (allErrs , field .Invalid (field .NewPath ("type" ), "" , fmt .Sprintf ("has invalid value: %v" , event .Type )))
58
+ }
59
+ if event .FirstTimestamp .Time != zeroTime {
60
+ allErrs = append (allErrs , field .Invalid (field .NewPath ("firstTimestamp" ), "" , "needs to be unset" ))
61
+ }
62
+ if event .LastTimestamp .Time != zeroTime {
63
+ allErrs = append (allErrs , field .Invalid (field .NewPath ("lastTimestamp" ), "" , "needs to be unset" ))
64
+ }
65
+ if event .Count != 0 {
66
+ allErrs = append (allErrs , field .Invalid (field .NewPath ("count" ), "" , "needs to be unset" ))
67
+ }
68
+ if event .Source .Component != "" || event .Source .Host != "" {
69
+ allErrs = append (allErrs , field .Invalid (field .NewPath ("source" ), "" , "needs to be unset" ))
70
+ }
71
+ return allErrs
72
+ }
73
+
74
+ func ValidateEventUpdate (newEvent , oldEvent * core.Event , requestVersion schema.GroupVersion ) field.ErrorList {
75
+ // Make sure the new event always passes legacy validation.
76
+ allErrs := legacyValidateEvent (newEvent )
77
+ if requestVersion == v1 .SchemeGroupVersion || requestVersion == eventsv1beta1 .SchemeGroupVersion {
78
+ // No further validation for backwards compatibility.
79
+ return allErrs
80
+ }
81
+
82
+ // Strict validation applies to update via events.k8s.io/v1 API and newer.
83
+ allErrs = append (allErrs , ValidateObjectMetaUpdate (& newEvent .ObjectMeta , & oldEvent .ObjectMeta , field .NewPath ("metadata" ))... )
84
+ // if the series was modified, validate the new data
85
+ if ! reflect .DeepEqual (newEvent .Series , oldEvent .Series ) {
86
+ allErrs = append (allErrs , validateV1EventSeries (newEvent )... )
87
+ }
88
+
89
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .InvolvedObject , oldEvent .InvolvedObject , field .NewPath ("involvedObject" ))... )
90
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .Reason , oldEvent .Reason , field .NewPath ("reason" ))... )
91
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .Message , oldEvent .Message , field .NewPath ("message" ))... )
92
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .Source , oldEvent .Source , field .NewPath ("source" ))... )
93
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .FirstTimestamp , oldEvent .FirstTimestamp , field .NewPath ("firstTimestamp" ))... )
94
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .LastTimestamp , oldEvent .LastTimestamp , field .NewPath ("lastTimestamp" ))... )
95
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .Count , oldEvent .Count , field .NewPath ("count" ))... )
96
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .Reason , oldEvent .Reason , field .NewPath ("reason" ))... )
97
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .Type , oldEvent .Type , field .NewPath ("type" ))... )
98
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .EventTime , oldEvent .EventTime , field .NewPath ("eventTime" ))... )
99
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .Action , oldEvent .Action , field .NewPath ("action" ))... )
100
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .Related , oldEvent .Related , field .NewPath ("related" ))... )
101
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .ReportingController , oldEvent .ReportingController , field .NewPath ("reportingController" ))... )
102
+ allErrs = append (allErrs , ValidateImmutableField (newEvent .ReportingInstance , oldEvent .ReportingInstance , field .NewPath ("reportingInstance" ))... )
103
+
104
+ return allErrs
105
+ }
106
+
107
+ func validateV1EventSeries (event * core.Event ) field.ErrorList {
108
+ allErrs := field.ErrorList {}
109
+ zeroTime := time.Time {}
110
+ if event .Series != nil {
111
+ if event .Series .Count < 2 {
112
+ allErrs = append (allErrs , field .Invalid (field .NewPath ("series.count" ), "" , fmt .Sprintf ("should be at least 2" )))
113
+ }
114
+ if event .Series .LastObservedTime .Time == zeroTime {
115
+ allErrs = append (allErrs , field .Required (field .NewPath ("series.lastObservedTime" ), "" ))
116
+ }
117
+ }
118
+ return allErrs
119
+ }
120
+
121
+ // legacyValidateEvent makes sure that the event makes sense.
122
+ func legacyValidateEvent (event * core.Event ) field.ErrorList {
38
123
allErrs := field.ErrorList {}
39
124
// Because go
40
125
zeroTime := time.Time {}
0 commit comments