From 79cbcf918e584bf10d508629bd63fa55ef1c189d Mon Sep 17 00:00:00 2001 From: saadali Date: Thu, 5 Feb 2015 18:21:01 -0800 Subject: [PATCH] Modify Event struct to allow compressing multiple recurring events in to a single event. # *** ERROR: *** Some API files are missing the required field descriptions # Add description tags to all non-inline fields in the following files: # pkg/api/v1beta1/types.go # pkg/api/v1beta2/types.go # # Your commit will be aborted unless you fix these. # COMMIT_BLOCKED_ON_DESCRIPTION --- pkg/api/testing/fuzzer.go | 16 ++++++++++++++++ pkg/api/types.go | 10 ++++++++-- pkg/api/v1beta1/conversion.go | 17 +++++++++++++++-- pkg/api/v1beta1/types.go | 11 +++++++++++ pkg/api/v1beta2/conversion.go | 16 ++++++++++++++-- pkg/api/v1beta2/types.go | 11 +++++++++++ pkg/api/v1beta3/types.go | 10 ++++++++-- pkg/client/events_test.go | 12 +++++++++--- pkg/client/record/event.go | 4 +++- pkg/client/record/event_test.go | 7 +++++-- pkg/kubectl/describe.go | 2 +- pkg/kubectl/describe_test.go | 24 +++++++++++++++--------- pkg/kubectl/resource_printer.go | 2 +- pkg/kubectl/resource_printer_test.go | 24 +++++++++++++++--------- pkg/kubectl/sorted_event_list.go | 2 +- pkg/kubectl/sorted_event_list_test.go | 24 +++++++++++++++--------- 16 files changed, 148 insertions(+), 44 deletions(-) diff --git a/pkg/api/testing/fuzzer.go b/pkg/api/testing/fuzzer.go index deb75534ae9..68818d945d5 100644 --- a/pkg/api/testing/fuzzer.go +++ b/pkg/api/testing/fuzzer.go @@ -211,6 +211,22 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { c.Fuzz(&ct.Privileged) c.Fuzz(&ct.Capabilities) }, + func(e *api.Event, c fuzz.Continue) { + // Fix event count to 1, otherwise, if a v1beta1 or v1beta2 event has a count set arbitrarily, it's count is ignored + c.Fuzz(&e.TypeMeta) + c.Fuzz(&e.ObjectMeta) + c.Fuzz(&e.InvolvedObject) + c.Fuzz(&e.Reason) + c.Fuzz(&e.Message) + c.Fuzz(&e.Source) + c.Fuzz(&e.FirstTimestamp) + c.Fuzz(&e.LastTimestamp) + if e.FirstTimestamp.IsZero() { + e.Count = 1 + } else { + c.Fuzz(&e.Count) + } + }, ) return f } diff --git a/pkg/api/types.go b/pkg/api/types.go index eda37ecb074..d9faa953358 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -1079,8 +1079,14 @@ type Event struct { // Optional. The component reporting this event. Should be a short machine understandable string. Source EventSource `json:"source,omitempty"` - // The time at which the client recorded the event. (Time of server receipt is in TypeMeta.) - Timestamp util.Time `json:"timestamp,omitempty"` + // The time at which the event was first recorded. (Time of server receipt is in TypeMeta.) + FirstTimestamp util.Time `json:"firstTimestamp,omitempty"` + + // The time at which the most recent occurance of this event was recorded. + LastTimestamp util.Time `json:"lastTimestamp,omitempty"` + + // The number of times this event has occurred. + Count int `json:"count,omitempty"` } // EventList is a list of events. diff --git a/pkg/api/v1beta1/conversion.go b/pkg/api/v1beta1/conversion.go index 40cefb37056..bc63bbb058e 100644 --- a/pkg/api/v1beta1/conversion.go +++ b/pkg/api/v1beta1/conversion.go @@ -898,7 +898,11 @@ func init() { out.Message = in.Message out.Source = in.Source.Component out.Host = in.Source.Host - out.Timestamp = in.Timestamp + out.Timestamp = in.FirstTimestamp + out.FirstTimestamp = in.FirstTimestamp + out.LastTimestamp = in.LastTimestamp + out.Count = in.Count + return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0) }, func(in *Event, out *newer.Event, s conversion.Scope) error { @@ -912,7 +916,16 @@ func init() { out.Message = in.Message out.Source.Component = in.Source out.Source.Host = in.Host - out.Timestamp = in.Timestamp + if in.FirstTimestamp.IsZero() { + // Assume this is an old event that does not specify FirstTimestamp/LastTimestamp/Count + out.FirstTimestamp = in.Timestamp + out.LastTimestamp = in.Timestamp + out.Count = 1 + } else { + out.FirstTimestamp = in.FirstTimestamp + out.LastTimestamp = in.LastTimestamp + out.Count = in.Count + } return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0) }, diff --git a/pkg/api/v1beta1/types.go b/pkg/api/v1beta1/types.go index 0586ae2f3b7..5d244693f1d 100644 --- a/pkg/api/v1beta1/types.go +++ b/pkg/api/v1beta1/types.go @@ -865,7 +865,18 @@ type Event struct { Host string `json:"host,omitempty" description:"host name on which this event was generated"` // The time at which the client recorded the event. (Time of server receipt is in TypeMeta.) + // Deprecated: Use InitialTimeStamp/LastSeenTimestamp/Count instead. + // For backwards compatability, this will map to IntialTimestamp. Timestamp util.Time `json:"timestamp,omitempty" description:"time at which the client recorded the event"` + + // The time at which the event was first recorded. (Time of server receipt is in TypeMeta.) + FirstTimestamp util.Time `json:"firstTimestamp,omitempty" description:"the time at which the event was first recorded"` + + // The time at which the most recent occurance of this event was recorded. + LastTimestamp util.Time `json:"lastTimestamp,omitempty" description:"the time at which the most recent occurance of this event was recorded"` + + // The number of times this event has occurred. + Count int `json:"count,omitempty" description:"the number of times this event has occurred"` } // EventList is a list of events. diff --git a/pkg/api/v1beta2/conversion.go b/pkg/api/v1beta2/conversion.go index 095c91037f8..da3fe378a25 100644 --- a/pkg/api/v1beta2/conversion.go +++ b/pkg/api/v1beta2/conversion.go @@ -819,7 +819,10 @@ func init() { out.Message = in.Message out.Source = in.Source.Component out.Host = in.Source.Host - out.Timestamp = in.Timestamp + out.Timestamp = in.FirstTimestamp + out.FirstTimestamp = in.FirstTimestamp + out.LastTimestamp = in.LastTimestamp + out.Count = in.Count return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0) }, func(in *Event, out *newer.Event, s conversion.Scope) error { @@ -833,7 +836,16 @@ func init() { out.Message = in.Message out.Source.Component = in.Source out.Source.Host = in.Host - out.Timestamp = in.Timestamp + if in.FirstTimestamp.IsZero() { + // Assume this is an old event that does not specify FirstTimestamp/LastTimestamp/Count + out.FirstTimestamp = in.Timestamp + out.LastTimestamp = in.Timestamp + out.Count = 1 + } else { + out.FirstTimestamp = in.FirstTimestamp + out.LastTimestamp = in.LastTimestamp + out.Count = in.Count + } return s.Convert(&in.InvolvedObject, &out.InvolvedObject, 0) }, diff --git a/pkg/api/v1beta2/types.go b/pkg/api/v1beta2/types.go index 47d83b9d00f..5a8cad5d588 100644 --- a/pkg/api/v1beta2/types.go +++ b/pkg/api/v1beta2/types.go @@ -840,7 +840,18 @@ type Event struct { Host string `json:"host,omitempty" description:"host name on which this event was generated"` // The time at which the client recorded the event. (Time of server receipt is in TypeMeta.) + // Deprecated: Use InitialTimeStamp/LastSeenTimestamp/Count instead. + // For backwards compatability, this will map to IntialTimestamp. Timestamp util.Time `json:"timestamp,omitempty" description:"time at which the client recorded the event"` + + // The time at which the event was first recorded. (Time of server receipt is in TypeMeta.) + FirstTimestamp util.Time `json:"firstTimestamp,omitempty" description:"the time at which the event was first recorded"` + + // The time at which the most recent occurance of this event was recorded. + LastTimestamp util.Time `json:"lastTimestamp,omitempty" description:"the time at which the most recent occurance of this event was recorded"` + + // The number of times this event has occurred. + Count int `json:"count,omitempty" description:"the number of times this event has occurred"` } // EventList is a list of events. diff --git a/pkg/api/v1beta3/types.go b/pkg/api/v1beta3/types.go index 94aa6326e0f..5e64ec17732 100644 --- a/pkg/api/v1beta3/types.go +++ b/pkg/api/v1beta3/types.go @@ -1058,8 +1058,14 @@ type Event struct { // Optional. The component reporting this event. Should be a short machine understandable string. Source EventSource `json:"source,omitempty"` - // The time at which the client recorded the event. (Time of server receipt is in TypeMeta.) - Timestamp util.Time `json:"timestamp,omitempty"` + // The time at which the event was first recorded. (Time of server receipt is in TypeMeta.) + FirstTimestamp util.Time `json:"firstTimestamp,omitempty"` + + // The time at which the most recent occurance of this event was recorded. + LastTimestamp util.Time `json:"lastTimestamp,omitempty"` + + // The number of times this event has occurred. + Count int `json:"count,omitempty"` } // EventList is a list of events. diff --git a/pkg/client/events_test.go b/pkg/client/events_test.go index 513b7a84ba8..171131a2620 100644 --- a/pkg/client/events_test.go +++ b/pkg/client/events_test.go @@ -64,7 +64,9 @@ func TestEventCreate(t *testing.T) { event := &api.Event{ //namespace: namespace{"default"}, InvolvedObject: *objReference, - Timestamp: timeStamp, + FirstTimestamp: timeStamp, + LastTimestamp: timeStamp, + Count: 1, } c := &testClient{ Request: testRequest{ @@ -98,7 +100,9 @@ func TestEventGet(t *testing.T) { timeStamp := util.Now() event := &api.Event{ InvolvedObject: *objReference, - Timestamp: timeStamp, + FirstTimestamp: timeStamp, + LastTimestamp: timeStamp, + Count: 1, } c := &testClient{ Request: testRequest{ @@ -135,7 +139,9 @@ func TestEventList(t *testing.T) { Items: []api.Event{ { InvolvedObject: *objReference, - Timestamp: timeStamp, + FirstTimestamp: timeStamp, + LastTimestamp: timeStamp, + Count: 1, }, }, } diff --git a/pkg/client/record/event.go b/pkg/client/record/event.go index d85306b8b71..860309861fb 100644 --- a/pkg/client/record/event.go +++ b/pkg/client/record/event.go @@ -170,7 +170,9 @@ func Event(object runtime.Object, reason, message string) { InvolvedObject: *ref, Reason: reason, Message: message, - Timestamp: t, + FirstTimestamp: t, + LastTimestamp: t, + Count: 1, } events.Action(watch.Added, e) diff --git a/pkg/client/record/event_test.go b/pkg/client/record/event_test.go index ff317376942..5600f012a7a 100644 --- a/pkg/client/record/event_test.go +++ b/pkg/client/record/event_test.go @@ -93,6 +93,7 @@ func TestEventf(t *testing.T) { Reason: "Started", Message: "some verbose message: 1", Source: api.EventSource{Component: "eventTest"}, + Count: 1, }, expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1beta1", ResourceVersion:"", FieldPath:"desiredState.manifest.containers[2]"}): reason: 'Started' some verbose message: 1`, }, @@ -116,6 +117,7 @@ func TestEventf(t *testing.T) { Reason: "Started", Message: "some verbose message: 1", Source: api.EventSource{Component: "eventTest"}, + Count: 1, }, expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1beta1", ResourceVersion:"", FieldPath:""}): reason: 'Started' some verbose message: 1`, }, @@ -127,10 +129,11 @@ func TestEventf(t *testing.T) { OnEvent: func(event *api.Event) (*api.Event, error) { a := *event // Just check that the timestamp was set. - if a.Timestamp.IsZero() { + if a.FirstTimestamp.IsZero() || a.LastTimestamp.IsZero() { t.Errorf("timestamp wasn't set") } - a.Timestamp = item.expect.Timestamp + a.FirstTimestamp = item.expect.FirstTimestamp + a.LastTimestamp = item.expect.LastTimestamp // Check that name has the right prefix. if n, en := a.Name, item.expect.Name; !strings.HasPrefix(n, en) { t.Errorf("Name '%v' does not contain prefix '%v'", n, en) diff --git a/pkg/kubectl/describe.go b/pkg/kubectl/describe.go index e9d8b985291..148a74ff73b 100644 --- a/pkg/kubectl/describe.go +++ b/pkg/kubectl/describe.go @@ -301,7 +301,7 @@ func describeEvents(el *api.EventList, w io.Writer) { fmt.Fprint(w, "Events:\nTime\tFrom\tSubobjectPath\tReason\tMessage\n") for _, e := range el.Items { fmt.Fprintf(w, "%s\t%v\t%v\t%v\t%v\n", - e.Timestamp.Time.Format(time.RFC1123Z), + e.FirstTimestamp.Time.Format(time.RFC1123Z), e.Source, e.InvolvedObject.FieldPath, e.Reason, diff --git a/pkg/kubectl/describe_test.go b/pkg/kubectl/describe_test.go index e965effd57c..53c10ca5a56 100644 --- a/pkg/kubectl/describe_test.go +++ b/pkg/kubectl/describe_test.go @@ -69,19 +69,25 @@ func TestPodDescribeResultsSorted(t *testing.T) { EventsList: api.EventList{ Items: []api.Event{ { - Source: api.EventSource{Component: "kubelet"}, - Message: "Item 1", - Timestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + Source: api.EventSource{Component: "kubelet"}, + Message: "Item 1", + FirstTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + LastTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + Count: 1, }, { - Source: api.EventSource{Component: "scheduler"}, - Message: "Item 2", - Timestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + Source: api.EventSource{Component: "scheduler"}, + Message: "Item 2", + FirstTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + LastTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + Count: 1, }, { - Source: api.EventSource{Component: "kubelet"}, - Message: "Item 3", - Timestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + Source: api.EventSource{Component: "kubelet"}, + Message: "Item 3", + FirstTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + LastTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + Count: 1, }, }, }, diff --git a/pkg/kubectl/resource_printer.go b/pkg/kubectl/resource_printer.go index 12679c644eb..efd85b62bb3 100644 --- a/pkg/kubectl/resource_printer.go +++ b/pkg/kubectl/resource_printer.go @@ -407,7 +407,7 @@ func printStatus(status *api.Status, w io.Writer) error { func printEvent(event *api.Event, w io.Writer) error { _, err := fmt.Fprintf( w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", - event.Timestamp.Time.Format(time.RFC1123Z), + event.FirstTimestamp.Time.Format(time.RFC1123Z), event.InvolvedObject.Name, event.InvolvedObject.Kind, event.InvolvedObject.FieldPath, diff --git a/pkg/kubectl/resource_printer_test.go b/pkg/kubectl/resource_printer_test.go index 20141e74187..f1a57f4747f 100644 --- a/pkg/kubectl/resource_printer_test.go +++ b/pkg/kubectl/resource_printer_test.go @@ -480,19 +480,25 @@ func TestPrintEventsResultSorted(t *testing.T) { obj := api.EventList{ Items: []api.Event{ { - Source: api.EventSource{Component: "kubelet"}, - Message: "Item 1", - Timestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + Source: api.EventSource{Component: "kubelet"}, + Message: "Item 1", + FirstTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + LastTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + Count: 1, }, { - Source: api.EventSource{Component: "scheduler"}, - Message: "Item 2", - Timestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + Source: api.EventSource{Component: "scheduler"}, + Message: "Item 2", + FirstTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + LastTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + Count: 1, }, { - Source: api.EventSource{Component: "kubelet"}, - Message: "Item 3", - Timestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + Source: api.EventSource{Component: "kubelet"}, + Message: "Item 3", + FirstTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + LastTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + Count: 1, }, }, } diff --git a/pkg/kubectl/sorted_event_list.go b/pkg/kubectl/sorted_event_list.go index 4e6a5ffb3d8..b37c25afbd8 100644 --- a/pkg/kubectl/sorted_event_list.go +++ b/pkg/kubectl/sorted_event_list.go @@ -32,5 +32,5 @@ func (list SortableEvents) Swap(i, j int) { } func (list SortableEvents) Less(i, j int) bool { - return list[i].Timestamp.Time.Before(list[j].Timestamp.Time) + return list[i].LastTimestamp.Time.Before(list[j].LastTimestamp.Time) } diff --git a/pkg/kubectl/sorted_event_list_test.go b/pkg/kubectl/sorted_event_list_test.go index 116e386fd6f..aa3618fee37 100644 --- a/pkg/kubectl/sorted_event_list_test.go +++ b/pkg/kubectl/sorted_event_list_test.go @@ -55,19 +55,25 @@ func TestSortableEvents(t *testing.T) { // Arrange list := SortableEvents([]api.Event{ { - Source: api.EventSource{Component: "kubelet"}, - Message: "Item 1", - Timestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + Source: api.EventSource{Component: "kubelet"}, + Message: "Item 1", + FirstTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + LastTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + Count: 1, }, { - Source: api.EventSource{Component: "scheduler"}, - Message: "Item 2", - Timestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + Source: api.EventSource{Component: "scheduler"}, + Message: "Item 2", + FirstTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + LastTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + Count: 1, }, { - Source: api.EventSource{Component: "kubelet"}, - Message: "Item 3", - Timestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + Source: api.EventSource{Component: "kubelet"}, + Message: "Item 3", + FirstTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + LastTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + Count: 1, }, })