Skip to content

Commit c23a4b0

Browse files
authored
Merge pull request kubernetes#92874 from chelseychen/event-api
Fix a few places where source field is empty when creating events via events/v1
2 parents 11348a3 + e010436 commit c23a4b0

File tree

16 files changed

+176
-188
lines changed

16 files changed

+176
-188
lines changed

pkg/apis/core/v1/conversion.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ func AddFieldLabelConversionsForEvent(scheme *runtime.Scheme) error {
435435
"involvedObject.resourceVersion",
436436
"involvedObject.fieldPath",
437437
"reason",
438+
"reportingComponent",
438439
"source",
439440
"type",
440441
"metadata.namespace",

pkg/apis/events/v1/conversion.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ limitations under the License.
1717
package v1
1818

1919
import (
20+
"fmt"
21+
2022
v1 "k8s.io/api/events/v1"
2123
conversion "k8s.io/apimachinery/pkg/conversion"
24+
"k8s.io/apimachinery/pkg/runtime"
2225
k8s_api "k8s.io/kubernetes/pkg/apis/core"
2326
k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1"
2427
)
@@ -56,3 +59,29 @@ func Convert_core_Event_To_v1_Event(in *k8s_api.Event, out *v1.Event, s conversi
5659
out.DeprecatedCount = in.Count
5760
return nil
5861
}
62+
63+
func AddFieldLabelConversionsForEvent(scheme *runtime.Scheme) error {
64+
mapping := map[string]string{
65+
"reason": "reason",
66+
"regarding.kind": "involvedObject.kind", // map events.k8s.io field to fieldset returned by ToSelectableFields
67+
"regarding.namespace": "involvedObject.namespace", // map events.k8s.io field to fieldset returned by ToSelectableFields
68+
"regarding.name": "involvedObject.name", // map events.k8s.io field to fieldset returned by ToSelectableFields
69+
"regarding.uid": "involvedObject.uid", // map events.k8s.io field to fieldset returned by ToSelectableFields
70+
"regarding.apiVersion": "involvedObject.apiVersion", // map events.k8s.io field to fieldset returned by ToSelectableFields
71+
"regarding.resourceVersion": "involvedObject.resourceVersion", // map events.k8s.io field to fieldset returned by ToSelectableFields
72+
"regarding.fieldPath": "involvedObject.fieldPath", // map events.k8s.io field to fieldset returned by ToSelectableFields
73+
"reportingController": "reportingComponent", // map events.k8s.io field to fieldset returned by ToSelectableFields
74+
"type": "type",
75+
"metadata.namespace": "metadata.namespace",
76+
"metadata.name": "metadata.name",
77+
}
78+
return scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("Event"),
79+
func(label, value string) (string, string, error) {
80+
mappedLabel, ok := mapping[label]
81+
if !ok {
82+
return "", "", fmt.Errorf("field label not supported: %s", label)
83+
}
84+
return mappedLabel, value, nil
85+
},
86+
)
87+
}

pkg/apis/events/v1/register.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,5 @@ func init() {
4141
// We only register manually written functions here. The registration of the
4242
// generated functions takes place in the generated files. The separation
4343
// makes the code compile even when the generated files are missing.
44-
localSchemeBuilder.Register(RegisterDefaults)
44+
localSchemeBuilder.Register(RegisterDefaults, AddFieldLabelConversionsForEvent)
4545
}

pkg/apis/events/v1beta1/conversion.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ limitations under the License.
1717
package v1beta1
1818

1919
import (
20+
"fmt"
21+
2022
v1beta1 "k8s.io/api/events/v1beta1"
2123
conversion "k8s.io/apimachinery/pkg/conversion"
24+
"k8s.io/apimachinery/pkg/runtime"
2225
k8s_api "k8s.io/kubernetes/pkg/apis/core"
2326
k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1"
2427
)
@@ -56,3 +59,29 @@ func Convert_core_Event_To_v1beta1_Event(in *k8s_api.Event, out *v1beta1.Event,
5659
out.DeprecatedCount = in.Count
5760
return nil
5861
}
62+
63+
func AddFieldLabelConversionsForEvent(scheme *runtime.Scheme) error {
64+
mapping := map[string]string{
65+
"reason": "reason",
66+
"regarding.kind": "involvedObject.kind", // map events.k8s.io field to fieldset returned by ToSelectableFields
67+
"regarding.namespace": "involvedObject.namespace", // map events.k8s.io field to fieldset returned by ToSelectableFields
68+
"regarding.name": "involvedObject.name", // map events.k8s.io field to fieldset returned by ToSelectableFields
69+
"regarding.uid": "involvedObject.uid", // map events.k8s.io field to fieldset returned by ToSelectableFields
70+
"regarding.apiVersion": "involvedObject.apiVersion", // map events.k8s.io field to fieldset returned by ToSelectableFields
71+
"regarding.resourceVersion": "involvedObject.resourceVersion", // map events.k8s.io field to fieldset returned by ToSelectableFields
72+
"regarding.fieldPath": "involvedObject.fieldPath", // map events.k8s.io field to fieldset returned by ToSelectableFields
73+
"reportingController": "reportingComponent", // map events.k8s.io field to fieldset returned by ToSelectableFields
74+
"type": "type",
75+
"metadata.namespace": "metadata.namespace",
76+
"metadata.name": "metadata.name",
77+
}
78+
return scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("Event"),
79+
func(label, value string) (string, string, error) {
80+
mappedLabel, ok := mapping[label]
81+
if !ok {
82+
return "", "", fmt.Errorf("field label not supported: %s", label)
83+
}
84+
return mappedLabel, value, nil
85+
},
86+
)
87+
}

pkg/apis/events/v1beta1/register.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,5 @@ func init() {
4141
// We only register manually written functions here. The registration of the
4242
// generated functions takes place in the generated files. The separation
4343
// makes the code compile even when the generated files are missing.
44-
localSchemeBuilder.Register(RegisterDefaults)
44+
localSchemeBuilder.Register(RegisterDefaults, AddFieldLabelConversionsForEvent)
4545
}

pkg/printers/internalversion/printers.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,7 +1757,7 @@ func printEvent(obj *api.Event, options printers.GenerateOptions) ([]metav1.Tabl
17571757
obj.Reason,
17581758
target,
17591759
obj.InvolvedObject.FieldPath,
1760-
formatEventSource(obj.Source),
1760+
formatEventSource(obj.Source, obj.ReportingController, obj.ReportingInstance),
17611761
strings.TrimSpace(obj.Message),
17621762
firstTimestamp,
17631763
int64(count),
@@ -2247,13 +2247,29 @@ func layoutContainerCells(containers []api.Container) (names string, images stri
22472247
return namesBuffer.String(), imagesBuffer.String()
22482248
}
22492249

2250-
// formatEventSource formats EventSource as a comma separated string excluding Host when empty
2251-
func formatEventSource(es api.EventSource) string {
2252-
EventSourceString := []string{es.Component}
2253-
if len(es.Host) > 0 {
2254-
EventSourceString = append(EventSourceString, es.Host)
2250+
// formatEventSource formats EventSource as a comma separated string excluding Host when empty.
2251+
// It uses reportingController when Source.Component is empty and reportingInstance when Source.Host is empty
2252+
func formatEventSource(es api.EventSource, reportingController, reportingInstance string) string {
2253+
return formatEventSourceComponentInstance(
2254+
firstNonEmpty(es.Component, reportingController),
2255+
firstNonEmpty(es.Host, reportingInstance),
2256+
)
2257+
}
2258+
2259+
func firstNonEmpty(ss ...string) string {
2260+
for _, s := range ss {
2261+
if len(s) > 0 {
2262+
return s
2263+
}
2264+
}
2265+
return ""
2266+
}
2267+
2268+
func formatEventSourceComponentInstance(component, instance string) string {
2269+
if len(instance) == 0 {
2270+
return component
22552271
}
2256-
return strings.Join(EventSourceString, ", ")
2272+
return component + ", " + instance
22572273
}
22582274

22592275
func printControllerRevision(obj *apps.ControllerRevision, options printers.GenerateOptions) ([]metav1.TableRow, error) {

pkg/printers/internalversion/printers_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,28 @@ func TestPrintEvent(t *testing.T) {
255255
// Columns: Last Seen, Type, Reason, Object, Subobject, Message, First Seen, Count, Name
256256
expected: []metav1.TableRow{{Cells: []interface{}{"3d", "Warning", "Event Reason", "deployment/Deployment Name", "spec.containers{foo}", "kubelet, Node1", "Message Data", "3d", int64(1), "event7"}}},
257257
},
258+
// Basic event, with empty Source; generate options=Wide
259+
{
260+
event: api.Event{
261+
ReportingController: "kubelet",
262+
ReportingInstance: "test",
263+
InvolvedObject: api.ObjectReference{
264+
Kind: "Deployment",
265+
Name: "Deployment Name",
266+
FieldPath: "spec.containers{foo}",
267+
},
268+
Reason: "Event Reason",
269+
Message: "Message Data",
270+
FirstTimestamp: metav1.Time{Time: time.Now().UTC().AddDate(0, 0, -3)},
271+
LastTimestamp: metav1.Time{Time: time.Now().UTC().AddDate(0, 0, -2)},
272+
Count: 6,
273+
Type: api.EventTypeWarning,
274+
ObjectMeta: metav1.ObjectMeta{Name: "event2"},
275+
},
276+
options: printers.GenerateOptions{Wide: true},
277+
// Columns: Last Seen, Type, Reason, Object, Subobject, Source, Message, First Seen, Count, Name
278+
expected: []metav1.TableRow{{Cells: []interface{}{"2d", "Warning", "Event Reason", "deployment/Deployment Name", "spec.containers{foo}", "kubelet, test", "Message Data", "3d", int64(6), "event2"}}},
279+
},
258280
}
259281

260282
for i, test := range tests {

pkg/registry/BUILD

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ filegroup(
6868
"//pkg/registry/core/serviceaccount:all-srcs",
6969
"//pkg/registry/discovery/endpointslice:all-srcs",
7070
"//pkg/registry/discovery/rest:all-srcs",
71-
"//pkg/registry/events/event:all-srcs",
7271
"//pkg/registry/events/rest:all-srcs",
7372
"//pkg/registry/extensions/rest:all-srcs",
7473
"//pkg/registry/flowcontrol/flowschema:all-srcs",

pkg/registry/core/event/strategy.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ func Matcher(label labels.Selector, field fields.Selector) storage.SelectionPred
104104
// ToSelectableFields returns a field set that represents the object.
105105
func ToSelectableFields(event *api.Event) fields.Set {
106106
objectMetaFieldsSet := generic.ObjectMetaFieldsSet(&event.ObjectMeta, true)
107+
source := event.Source.Component
108+
if source == "" {
109+
source = event.ReportingController
110+
}
107111
specificFieldsSet := fields.Set{
108112
"involvedObject.kind": event.InvolvedObject.Kind,
109113
"involvedObject.namespace": event.InvolvedObject.Namespace,
@@ -113,7 +117,8 @@ func ToSelectableFields(event *api.Event) fields.Set {
113117
"involvedObject.resourceVersion": event.InvolvedObject.ResourceVersion,
114118
"involvedObject.fieldPath": event.InvolvedObject.FieldPath,
115119
"reason": event.Reason,
116-
"source": event.Source.Component,
120+
"reportingComponent": event.ReportingController, // use the core/v1 field name
121+
"source": source,
117122
"type": event.Type,
118123
}
119124
return generic.MergeFieldsSets(objectMetaFieldsSet, specificFieldsSet)

pkg/registry/core/event/strategy_test.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func TestGetAttrs(t *testing.T) {
5050
Type: api.EventTypeNormal,
5151
}
5252
field := ToSelectableFields(eventA)
53-
expect := fields.Set{
53+
expectA := fields.Set{
5454
"metadata.name": "f0118",
5555
"metadata.namespace": "default",
5656
"involvedObject.kind": "Pod",
@@ -61,10 +61,49 @@ func TestGetAttrs(t *testing.T) {
6161
"involvedObject.resourceVersion": "0",
6262
"involvedObject.fieldPath": "",
6363
"reason": "ForTesting",
64+
"reportingComponent": "",
6465
"source": "test",
6566
"type": api.EventTypeNormal,
6667
}
67-
if e, a := expect, field; !reflect.DeepEqual(e, a) {
68+
if e, a := expectA, field; !reflect.DeepEqual(e, a) {
69+
t.Errorf("diff: %s", diff.ObjectDiff(e, a))
70+
}
71+
72+
eventB := &api.Event{
73+
ObjectMeta: metav1.ObjectMeta{
74+
Name: "f0118",
75+
Namespace: "default",
76+
},
77+
InvolvedObject: api.ObjectReference{
78+
Kind: "Pod",
79+
Name: "foo",
80+
Namespace: "baz",
81+
UID: "long uid string",
82+
APIVersion: "v1",
83+
ResourceVersion: "0",
84+
FieldPath: "",
85+
},
86+
Reason: "ForTesting",
87+
ReportingController: "test",
88+
Type: api.EventTypeNormal,
89+
}
90+
field = ToSelectableFields(eventB)
91+
expectB := fields.Set{
92+
"metadata.name": "f0118",
93+
"metadata.namespace": "default",
94+
"involvedObject.kind": "Pod",
95+
"involvedObject.name": "foo",
96+
"involvedObject.namespace": "baz",
97+
"involvedObject.uid": "long uid string",
98+
"involvedObject.apiVersion": "v1",
99+
"involvedObject.resourceVersion": "0",
100+
"involvedObject.fieldPath": "",
101+
"reason": "ForTesting",
102+
"reportingComponent": "test",
103+
"source": "test",
104+
"type": api.EventTypeNormal,
105+
}
106+
if e, a := expectB, field; !reflect.DeepEqual(e, a) {
68107
t.Errorf("diff: %s", diff.ObjectDiff(e, a))
69108
}
70109
}

0 commit comments

Comments
 (0)