Merge pull request #92874 from chelseychen/event-api

Fix a few places where source field is empty when creating events via events/v1
This commit is contained in:
Kubernetes Prow Robot 2020-07-11 20:57:31 -07:00 committed by GitHub
commit c23a4b08d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 176 additions and 188 deletions

View File

@ -435,6 +435,7 @@ func AddFieldLabelConversionsForEvent(scheme *runtime.Scheme) error {
"involvedObject.resourceVersion", "involvedObject.resourceVersion",
"involvedObject.fieldPath", "involvedObject.fieldPath",
"reason", "reason",
"reportingComponent",
"source", "source",
"type", "type",
"metadata.namespace", "metadata.namespace",

View File

@ -17,8 +17,11 @@ limitations under the License.
package v1 package v1
import ( import (
"fmt"
v1 "k8s.io/api/events/v1" v1 "k8s.io/api/events/v1"
conversion "k8s.io/apimachinery/pkg/conversion" conversion "k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
k8s_api "k8s.io/kubernetes/pkg/apis/core" k8s_api "k8s.io/kubernetes/pkg/apis/core"
k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1"
) )
@ -56,3 +59,29 @@ func Convert_core_Event_To_v1_Event(in *k8s_api.Event, out *v1.Event, s conversi
out.DeprecatedCount = in.Count out.DeprecatedCount = in.Count
return nil return nil
} }
func AddFieldLabelConversionsForEvent(scheme *runtime.Scheme) error {
mapping := map[string]string{
"reason": "reason",
"regarding.kind": "involvedObject.kind", // map events.k8s.io field to fieldset returned by ToSelectableFields
"regarding.namespace": "involvedObject.namespace", // map events.k8s.io field to fieldset returned by ToSelectableFields
"regarding.name": "involvedObject.name", // map events.k8s.io field to fieldset returned by ToSelectableFields
"regarding.uid": "involvedObject.uid", // map events.k8s.io field to fieldset returned by ToSelectableFields
"regarding.apiVersion": "involvedObject.apiVersion", // map events.k8s.io field to fieldset returned by ToSelectableFields
"regarding.resourceVersion": "involvedObject.resourceVersion", // map events.k8s.io field to fieldset returned by ToSelectableFields
"regarding.fieldPath": "involvedObject.fieldPath", // map events.k8s.io field to fieldset returned by ToSelectableFields
"reportingController": "reportingComponent", // map events.k8s.io field to fieldset returned by ToSelectableFields
"type": "type",
"metadata.namespace": "metadata.namespace",
"metadata.name": "metadata.name",
}
return scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("Event"),
func(label, value string) (string, string, error) {
mappedLabel, ok := mapping[label]
if !ok {
return "", "", fmt.Errorf("field label not supported: %s", label)
}
return mappedLabel, value, nil
},
)
}

View File

@ -41,5 +41,5 @@ func init() {
// We only register manually written functions here. The registration of the // We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation // generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing. // makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(RegisterDefaults) localSchemeBuilder.Register(RegisterDefaults, AddFieldLabelConversionsForEvent)
} }

View File

@ -17,8 +17,11 @@ limitations under the License.
package v1beta1 package v1beta1
import ( import (
"fmt"
v1beta1 "k8s.io/api/events/v1beta1" v1beta1 "k8s.io/api/events/v1beta1"
conversion "k8s.io/apimachinery/pkg/conversion" conversion "k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
k8s_api "k8s.io/kubernetes/pkg/apis/core" k8s_api "k8s.io/kubernetes/pkg/apis/core"
k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1"
) )
@ -56,3 +59,29 @@ func Convert_core_Event_To_v1beta1_Event(in *k8s_api.Event, out *v1beta1.Event,
out.DeprecatedCount = in.Count out.DeprecatedCount = in.Count
return nil return nil
} }
func AddFieldLabelConversionsForEvent(scheme *runtime.Scheme) error {
mapping := map[string]string{
"reason": "reason",
"regarding.kind": "involvedObject.kind", // map events.k8s.io field to fieldset returned by ToSelectableFields
"regarding.namespace": "involvedObject.namespace", // map events.k8s.io field to fieldset returned by ToSelectableFields
"regarding.name": "involvedObject.name", // map events.k8s.io field to fieldset returned by ToSelectableFields
"regarding.uid": "involvedObject.uid", // map events.k8s.io field to fieldset returned by ToSelectableFields
"regarding.apiVersion": "involvedObject.apiVersion", // map events.k8s.io field to fieldset returned by ToSelectableFields
"regarding.resourceVersion": "involvedObject.resourceVersion", // map events.k8s.io field to fieldset returned by ToSelectableFields
"regarding.fieldPath": "involvedObject.fieldPath", // map events.k8s.io field to fieldset returned by ToSelectableFields
"reportingController": "reportingComponent", // map events.k8s.io field to fieldset returned by ToSelectableFields
"type": "type",
"metadata.namespace": "metadata.namespace",
"metadata.name": "metadata.name",
}
return scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("Event"),
func(label, value string) (string, string, error) {
mappedLabel, ok := mapping[label]
if !ok {
return "", "", fmt.Errorf("field label not supported: %s", label)
}
return mappedLabel, value, nil
},
)
}

View File

@ -41,5 +41,5 @@ func init() {
// We only register manually written functions here. The registration of the // We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation // generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing. // makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(RegisterDefaults) localSchemeBuilder.Register(RegisterDefaults, AddFieldLabelConversionsForEvent)
} }

View File

@ -1757,7 +1757,7 @@ func printEvent(obj *api.Event, options printers.GenerateOptions) ([]metav1.Tabl
obj.Reason, obj.Reason,
target, target,
obj.InvolvedObject.FieldPath, obj.InvolvedObject.FieldPath,
formatEventSource(obj.Source), formatEventSource(obj.Source, obj.ReportingController, obj.ReportingInstance),
strings.TrimSpace(obj.Message), strings.TrimSpace(obj.Message),
firstTimestamp, firstTimestamp,
int64(count), int64(count),
@ -2247,13 +2247,29 @@ func layoutContainerCells(containers []api.Container) (names string, images stri
return namesBuffer.String(), imagesBuffer.String() return namesBuffer.String(), imagesBuffer.String()
} }
// formatEventSource formats EventSource as a comma separated string excluding Host when empty // formatEventSource formats EventSource as a comma separated string excluding Host when empty.
func formatEventSource(es api.EventSource) string { // It uses reportingController when Source.Component is empty and reportingInstance when Source.Host is empty
EventSourceString := []string{es.Component} func formatEventSource(es api.EventSource, reportingController, reportingInstance string) string {
if len(es.Host) > 0 { return formatEventSourceComponentInstance(
EventSourceString = append(EventSourceString, es.Host) firstNonEmpty(es.Component, reportingController),
firstNonEmpty(es.Host, reportingInstance),
)
}
func firstNonEmpty(ss ...string) string {
for _, s := range ss {
if len(s) > 0 {
return s
}
} }
return strings.Join(EventSourceString, ", ") return ""
}
func formatEventSourceComponentInstance(component, instance string) string {
if len(instance) == 0 {
return component
}
return component + ", " + instance
} }
func printControllerRevision(obj *apps.ControllerRevision, options printers.GenerateOptions) ([]metav1.TableRow, error) { func printControllerRevision(obj *apps.ControllerRevision, options printers.GenerateOptions) ([]metav1.TableRow, error) {

View File

@ -255,6 +255,28 @@ func TestPrintEvent(t *testing.T) {
// Columns: Last Seen, Type, Reason, Object, Subobject, Message, First Seen, Count, Name // Columns: Last Seen, Type, Reason, Object, Subobject, Message, First Seen, Count, Name
expected: []metav1.TableRow{{Cells: []interface{}{"3d", "Warning", "Event Reason", "deployment/Deployment Name", "spec.containers{foo}", "kubelet, Node1", "Message Data", "3d", int64(1), "event7"}}}, expected: []metav1.TableRow{{Cells: []interface{}{"3d", "Warning", "Event Reason", "deployment/Deployment Name", "spec.containers{foo}", "kubelet, Node1", "Message Data", "3d", int64(1), "event7"}}},
}, },
// Basic event, with empty Source; generate options=Wide
{
event: api.Event{
ReportingController: "kubelet",
ReportingInstance: "test",
InvolvedObject: api.ObjectReference{
Kind: "Deployment",
Name: "Deployment Name",
FieldPath: "spec.containers{foo}",
},
Reason: "Event Reason",
Message: "Message Data",
FirstTimestamp: metav1.Time{Time: time.Now().UTC().AddDate(0, 0, -3)},
LastTimestamp: metav1.Time{Time: time.Now().UTC().AddDate(0, 0, -2)},
Count: 6,
Type: api.EventTypeWarning,
ObjectMeta: metav1.ObjectMeta{Name: "event2"},
},
options: printers.GenerateOptions{Wide: true},
// Columns: Last Seen, Type, Reason, Object, Subobject, Source, Message, First Seen, Count, Name
expected: []metav1.TableRow{{Cells: []interface{}{"2d", "Warning", "Event Reason", "deployment/Deployment Name", "spec.containers{foo}", "kubelet, test", "Message Data", "3d", int64(6), "event2"}}},
},
} }
for i, test := range tests { for i, test := range tests {

View File

@ -68,7 +68,6 @@ filegroup(
"//pkg/registry/core/serviceaccount:all-srcs", "//pkg/registry/core/serviceaccount:all-srcs",
"//pkg/registry/discovery/endpointslice:all-srcs", "//pkg/registry/discovery/endpointslice:all-srcs",
"//pkg/registry/discovery/rest:all-srcs", "//pkg/registry/discovery/rest:all-srcs",
"//pkg/registry/events/event:all-srcs",
"//pkg/registry/events/rest:all-srcs", "//pkg/registry/events/rest:all-srcs",
"//pkg/registry/extensions/rest:all-srcs", "//pkg/registry/extensions/rest:all-srcs",
"//pkg/registry/flowcontrol/flowschema:all-srcs", "//pkg/registry/flowcontrol/flowschema:all-srcs",

View File

@ -104,6 +104,10 @@ func Matcher(label labels.Selector, field fields.Selector) storage.SelectionPred
// ToSelectableFields returns a field set that represents the object. // ToSelectableFields returns a field set that represents the object.
func ToSelectableFields(event *api.Event) fields.Set { func ToSelectableFields(event *api.Event) fields.Set {
objectMetaFieldsSet := generic.ObjectMetaFieldsSet(&event.ObjectMeta, true) objectMetaFieldsSet := generic.ObjectMetaFieldsSet(&event.ObjectMeta, true)
source := event.Source.Component
if source == "" {
source = event.ReportingController
}
specificFieldsSet := fields.Set{ specificFieldsSet := fields.Set{
"involvedObject.kind": event.InvolvedObject.Kind, "involvedObject.kind": event.InvolvedObject.Kind,
"involvedObject.namespace": event.InvolvedObject.Namespace, "involvedObject.namespace": event.InvolvedObject.Namespace,
@ -113,7 +117,8 @@ func ToSelectableFields(event *api.Event) fields.Set {
"involvedObject.resourceVersion": event.InvolvedObject.ResourceVersion, "involvedObject.resourceVersion": event.InvolvedObject.ResourceVersion,
"involvedObject.fieldPath": event.InvolvedObject.FieldPath, "involvedObject.fieldPath": event.InvolvedObject.FieldPath,
"reason": event.Reason, "reason": event.Reason,
"source": event.Source.Component, "reportingComponent": event.ReportingController, // use the core/v1 field name
"source": source,
"type": event.Type, "type": event.Type,
} }
return generic.MergeFieldsSets(objectMetaFieldsSet, specificFieldsSet) return generic.MergeFieldsSets(objectMetaFieldsSet, specificFieldsSet)

View File

@ -50,7 +50,7 @@ func TestGetAttrs(t *testing.T) {
Type: api.EventTypeNormal, Type: api.EventTypeNormal,
} }
field := ToSelectableFields(eventA) field := ToSelectableFields(eventA)
expect := fields.Set{ expectA := fields.Set{
"metadata.name": "f0118", "metadata.name": "f0118",
"metadata.namespace": "default", "metadata.namespace": "default",
"involvedObject.kind": "Pod", "involvedObject.kind": "Pod",
@ -61,10 +61,49 @@ func TestGetAttrs(t *testing.T) {
"involvedObject.resourceVersion": "0", "involvedObject.resourceVersion": "0",
"involvedObject.fieldPath": "", "involvedObject.fieldPath": "",
"reason": "ForTesting", "reason": "ForTesting",
"reportingComponent": "",
"source": "test", "source": "test",
"type": api.EventTypeNormal, "type": api.EventTypeNormal,
} }
if e, a := expect, field; !reflect.DeepEqual(e, a) { if e, a := expectA, field; !reflect.DeepEqual(e, a) {
t.Errorf("diff: %s", diff.ObjectDiff(e, a))
}
eventB := &api.Event{
ObjectMeta: metav1.ObjectMeta{
Name: "f0118",
Namespace: "default",
},
InvolvedObject: api.ObjectReference{
Kind: "Pod",
Name: "foo",
Namespace: "baz",
UID: "long uid string",
APIVersion: "v1",
ResourceVersion: "0",
FieldPath: "",
},
Reason: "ForTesting",
ReportingController: "test",
Type: api.EventTypeNormal,
}
field = ToSelectableFields(eventB)
expectB := fields.Set{
"metadata.name": "f0118",
"metadata.namespace": "default",
"involvedObject.kind": "Pod",
"involvedObject.name": "foo",
"involvedObject.namespace": "baz",
"involvedObject.uid": "long uid string",
"involvedObject.apiVersion": "v1",
"involvedObject.resourceVersion": "0",
"involvedObject.fieldPath": "",
"reason": "ForTesting",
"reportingComponent": "test",
"source": "test",
"type": api.EventTypeNormal,
}
if e, a := expectB, field; !reflect.DeepEqual(e, a) {
t.Errorf("diff: %s", diff.ObjectDiff(e, a)) t.Errorf("diff: %s", diff.ObjectDiff(e, a))
} }
} }

View File

@ -1,39 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"strategy.go",
],
importpath = "k8s.io/kubernetes/pkg/registry/events/event",
visibility = ["//visibility:public"],
deps = [
"//pkg/api/legacyscheme:go_default_library",
"//pkg/apis/core:go_default_library",
"//pkg/apis/core/validation:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/registry/generic:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -1,17 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package event // import "k8s.io/kubernetes/pkg/registry/events/event"

View File

@ -1,117 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package event
import (
"context"
"fmt"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation/field"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/registry/generic"
apistorage "k8s.io/apiserver/pkg/storage"
"k8s.io/apiserver/pkg/storage/names"
"k8s.io/kubernetes/pkg/api/legacyscheme"
coreapi "k8s.io/kubernetes/pkg/apis/core"
corevalidation "k8s.io/kubernetes/pkg/apis/core/validation"
)
// eventStrategy implements verification logic for Pod Presets.
type eventStrategy struct {
runtime.ObjectTyper
names.NameGenerator
}
// Strategy is the default logic that applies when creating and updating Pod Preset objects.
var Strategy = eventStrategy{legacyscheme.Scheme, names.SimpleNameGenerator}
// NamespaceScoped returns true because all Events need to be within a namespace.
func (eventStrategy) NamespaceScoped() bool {
return true
}
// PrepareForCreate clears the status of a Pod Preset before creation.
func (eventStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (eventStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
}
// Validate validates a new Event.
func (eventStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
groupVersion := requestGroupVersion(ctx)
event := obj.(*coreapi.Event)
return corevalidation.ValidateEventCreate(event, groupVersion)
}
// Canonicalize normalizes the object after validation.
// AllowCreateOnUpdate is false for Event; this means POST is needed to create one.
func (eventStrategy) AllowCreateOnUpdate() bool {
return false
}
func (eventStrategy) Canonicalize(obj runtime.Object) {}
// ValidateUpdate is the default update validation for an end user.
func (eventStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
groupVersion := requestGroupVersion(ctx)
event := obj.(*coreapi.Event)
oldEvent := old.(*coreapi.Event)
return corevalidation.ValidateEventUpdate(event, oldEvent, groupVersion)
}
// AllowUnconditionalUpdate is the default update policy for Event objects.
func (eventStrategy) AllowUnconditionalUpdate() bool {
return true
}
// SelectableFields returns a field set that represents the object.
func SelectableFields(pip *coreapi.Event) fields.Set {
return generic.ObjectMetaFieldsSet(&pip.ObjectMeta, true)
}
// GetAttrs returns labels and fields of a given object for filtering purposes.
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
pip, ok := obj.(*coreapi.Event)
if !ok {
return nil, nil, fmt.Errorf("given object is not a Event")
}
return labels.Set(pip.ObjectMeta.Labels), SelectableFields(pip), nil
}
// Matcher is the filter used by the generic etcd backend to watch events
// from etcd to clients of the apiserver only interested in specific labels/fields.
func Matcher(label labels.Selector, field fields.Selector) apistorage.SelectionPredicate {
return apistorage.SelectionPredicate{
Label: label,
Field: field,
GetAttrs: GetAttrs,
}
}
// requestGroupVersion returns the group/version associated with the given context, or a zero-value group/version.
func requestGroupVersion(ctx context.Context) schema.GroupVersion {
if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found {
return schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion}
}
return schema.GroupVersion{}
}

View File

@ -153,7 +153,8 @@ func (f *EventSourceObjectSpamFilter) Filter(event *v1.Event) bool {
// localKey - key that makes this event in the local group // localKey - key that makes this event in the local group
type EventAggregatorKeyFunc func(event *v1.Event) (aggregateKey string, localKey string) type EventAggregatorKeyFunc func(event *v1.Event) (aggregateKey string, localKey string)
// EventAggregatorByReasonFunc aggregates events by exact match on event.Source, event.InvolvedObject, event.Type and event.Reason // EventAggregatorByReasonFunc aggregates events by exact match on event.Source, event.InvolvedObject, event.Type,
// event.Reason, event.ReportingController and event.ReportingInstance
func EventAggregatorByReasonFunc(event *v1.Event) (string, string) { func EventAggregatorByReasonFunc(event *v1.Event) (string, string) {
return strings.Join([]string{ return strings.Join([]string{
event.Source.Component, event.Source.Component,
@ -165,6 +166,8 @@ func EventAggregatorByReasonFunc(event *v1.Event) (string, string) {
event.InvolvedObject.APIVersion, event.InvolvedObject.APIVersion,
event.Type, event.Type,
event.Reason, event.Reason,
event.ReportingController,
event.ReportingInstance,
}, },
""), event.Message ""), event.Message
} }

View File

@ -19,6 +19,7 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/typed/events/v1:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/typed/events/v1:go_default_library",
"//test/e2e/framework:go_default_library", "//test/e2e/framework:go_default_library",
"//test/e2e/instrumentation/common:go_default_library", "//test/e2e/instrumentation/common:go_default_library",

View File

@ -22,11 +22,12 @@ import (
"fmt" "fmt"
"time" "time"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
eventsv1 "k8s.io/api/events/v1" eventsv1 "k8s.io/api/events/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality" apiequality "k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/diff"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
typedeventsv1 "k8s.io/client-go/kubernetes/typed/events/v1" typedeventsv1 "k8s.io/client-go/kubernetes/typed/events/v1"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/instrumentation/common" "k8s.io/kubernetes/test/e2e/instrumentation/common"
@ -73,10 +74,12 @@ func eventExistsInList(client typedeventsv1.EventInterface, namespace, name stri
var _ = common.SIGDescribe("Events API", func() { var _ = common.SIGDescribe("Events API", func() {
f := framework.NewDefaultFramework("events") f := framework.NewDefaultFramework("events")
var coreClient corev1.EventInterface
var client typedeventsv1.EventInterface var client typedeventsv1.EventInterface
var clientAllNamespaces typedeventsv1.EventInterface var clientAllNamespaces typedeventsv1.EventInterface
ginkgo.BeforeEach(func() { ginkgo.BeforeEach(func() {
coreClient = f.ClientSet.CoreV1().Events(f.Namespace.Name)
client = f.ClientSet.EventsV1().Events(f.Namespace.Name) client = f.ClientSet.EventsV1().Events(f.Namespace.Name)
clientAllNamespaces = f.ClientSet.EventsV1().Events(metav1.NamespaceAll) clientAllNamespaces = f.ClientSet.EventsV1().Events(metav1.NamespaceAll)
}) })
@ -103,6 +106,20 @@ var _ = common.SIGDescribe("Events API", func() {
foundCreatedEvent = eventExistsInList(client, f.Namespace.Name, eventName) foundCreatedEvent = eventExistsInList(client, f.Namespace.Name, eventName)
framework.ExpectEqual(foundCreatedEvent, true, "failed to find test event in list with namespace scope") framework.ExpectEqual(foundCreatedEvent, true, "failed to find test event in list with namespace scope")
ginkgo.By("listing events with field selection filtering on source")
filteredCoreV1List, err := coreClient.List(context.TODO(), metav1.ListOptions{FieldSelector: "source=test-controller"})
framework.ExpectNoError(err, "failed to get filtered list")
if len(filteredCoreV1List.Items) != 1 || filteredCoreV1List.Items[0].Name != eventName {
framework.Failf("expected single event, got %#v", filteredCoreV1List.Items)
}
ginkgo.By("listing events with field selection filtering on reportingController")
filteredEventsV1List, err := client.List(context.TODO(), metav1.ListOptions{FieldSelector: "reportingController=test-controller"})
framework.ExpectNoError(err, "failed to get filtered list")
if len(filteredEventsV1List.Items) != 1 || filteredEventsV1List.Items[0].Name != eventName {
framework.Failf("expected single event, got %#v", filteredEventsV1List.Items)
}
ginkgo.By("getting the test event") ginkgo.By("getting the test event")
testEvent, err := client.Get(context.TODO(), eventName, metav1.GetOptions{}) testEvent, err := client.Get(context.TODO(), eventName, metav1.GetOptions{})
framework.ExpectNoError(err, "failed to get test event") framework.ExpectNoError(err, "failed to get test event")