diff --git a/pkg/client/events.go b/pkg/client/events.go index 6b3e8380d5f..a40a87991a2 100644 --- a/pkg/client/events.go +++ b/pkg/client/events.go @@ -42,6 +42,9 @@ type EventInterface interface { // Search finds events about the specified object Search(objOrRef runtime.Object) (*api.EventList, error) Delete(name string) error + // Returns the appropriate field selector based on the API version being used to communicate with the server. + // The returned field selector can be used with List and Watch to filter desired events. + GetFieldSelector(involvedObjectName, involvedObjectNamespace, involvedObjectKind, involvedObjectUID *string) fields.Selector } // events implements Events interface @@ -148,20 +151,13 @@ func (e *events) Search(objOrRef runtime.Object) (*api.EventList, error) { if e.namespace != "" && ref.Namespace != e.namespace { return nil, fmt.Errorf("won't be able to find any events of namespace '%v' in namespace '%v'", ref.Namespace, e.namespace) } - fields := fields.Set{} - if ref.Kind != "" { - fields["involvedObject.kind"] = ref.Kind + stringRefUID := string(ref.UID) + var refUID *string + if stringRefUID != "" { + refUID = &stringRefUID } - if ref.Namespace != "" { - fields["involvedObject.namespace"] = ref.Namespace - } - if ref.Name != "" { - fields["involvedObject.name"] = ref.Name - } - if ref.UID != "" { - fields["involvedObject.uid"] = string(ref.UID) - } - return e.List(labels.Everything(), fields.AsSelector()) + fieldSelector := e.GetFieldSelector(&ref.Name, &ref.Namespace, &ref.Kind, refUID) + return e.List(labels.Everything(), fieldSelector) } // Delete deletes an existing event. @@ -173,3 +169,31 @@ func (e *events) Delete(name string) error { Do(). Error() } + +// Returns the appropriate field selector based on the API version being used to communicate with the server. +// The returned field selector can be used with List and Watch to filter desired events. +func (e *events) GetFieldSelector(involvedObjectName, involvedObjectNamespace, involvedObjectKind, involvedObjectUID *string) fields.Selector { + apiVersion := e.client.APIVersion() + field := fields.Set{} + if involvedObjectName != nil { + field[getInvolvedObjectNameFieldLabel(apiVersion)] = *involvedObjectName + } + if involvedObjectNamespace != nil { + field["involvedObject.namespace"] = *involvedObjectNamespace + } + if involvedObjectKind != nil { + field["involvedObject.kind"] = *involvedObjectKind + } + if involvedObjectUID != nil { + field["involvedObject.uid"] = *involvedObjectUID + } + return field.AsSelector() +} + +// Returns the appropriate field label to use for name of the involved object as per the given API version. +func getInvolvedObjectNameFieldLabel(version string) string { + if api.PreV1Beta3(version) { + return "involvedObject.id" + } + return "involvedObject.name" +} diff --git a/pkg/client/events_test.go b/pkg/client/events_test.go index ed07998930d..2f7f686a248 100644 --- a/pkg/client/events_test.go +++ b/pkg/client/events_test.go @@ -34,7 +34,11 @@ func TestEventSearch(t *testing.T) { Method: "GET", Path: "/events", Query: url.Values{ - "fields": []string{"involvedObject.kind=Pod,involvedObject.name=foo,involvedObject.namespace=baz"}, + "fields": []string{ + "involvedObject.kind=Pod,", + getInvolvedObjectNameFieldLabel(testapi.Version()) + "=foo,", + "involvedObject.namespace=baz", + }, "labels": []string{}, }, }, diff --git a/pkg/client/fake_events.go b/pkg/client/fake_events.go index aee04e13521..108e26f412b 100644 --- a/pkg/client/fake_events.go +++ b/pkg/client/fake_events.go @@ -70,3 +70,8 @@ func (c *FakeEvents) Delete(name string) error { c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-event", Value: name}) return nil } + +func (c *FakeEvents) GetFieldSelector(involvedObjectName, involvedObjectNamespace, involvedObjectKind, involvedObjectUID *string) fields.Selector { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "get-field-selector"}) + return fields.Everything() +} diff --git a/pkg/kubectl/describe.go b/pkg/kubectl/describe.go index 69756aceabb..60a48a36df2 100644 --- a/pkg/kubectl/describe.go +++ b/pkg/kubectl/describe.go @@ -26,7 +26,6 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" - "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/golang/glog" ) @@ -204,13 +203,10 @@ func (d *PodDescriber) Describe(namespace, name string) (string, error) { pod, err := pc.Get(name) if err != nil { - events, err2 := d.Events(namespace).List( + eventsInterface := d.Events(namespace) + events, err2 := eventsInterface.List( labels.Everything(), - fields.Set{ - "involvedObject.name": name, - "involvedObject.namespace": namespace, - }.AsSelector(), - ) + eventsInterface.GetFieldSelector(&name, &namespace, nil, nil)) if err2 == nil && len(events.Items) > 0 { return tabbedString(func(out io.Writer) error { fmt.Fprintf(out, "Pod '%v': error '%v', but found events.\n", name, err) diff --git a/pkg/registry/event/rest.go b/pkg/registry/event/rest.go index 18d2a669c93..708d3de7006 100644 --- a/pkg/registry/event/rest.go +++ b/pkg/registry/event/rest.go @@ -117,7 +117,6 @@ func (rs *REST) getAttrs(obj runtime.Object) (objLabels labels.Set, objFields fi if !ok { return nil, nil, fmt.Errorf("invalid object type") } - // TODO: internal version leaks through here. This should be versioned. return labels.Set{}, fields.Set{ "involvedObject.kind": event.InvolvedObject.Kind, "involvedObject.namespace": event.InvolvedObject.Namespace,