diff --git a/pkg/api/ref.go b/pkg/api/ref.go index c21533fe7fa..36eb647eb19 100644 --- a/pkg/api/ref.go +++ b/pkg/api/ref.go @@ -49,10 +49,10 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) { return nil, fmt.Errorf("unexpected self link format: %v", meta.SelfLink()) } return &ObjectReference{ - Kind: kind, - APIVersion: version[1], - // TODO: correct Name and UID when TypeMeta makes a distinction + Kind: kind, + APIVersion: version[1], Name: meta.Name(), + Namespace: meta.Namespace(), UID: meta.UID(), ResourceVersion: meta.ResourceVersion(), }, nil diff --git a/pkg/client/events.go b/pkg/client/events.go index aa22996f992..a0123bdb168 100644 --- a/pkg/client/events.go +++ b/pkg/client/events.go @@ -50,7 +50,7 @@ func newEvents(c *Client) *events { // Create makes a new event. Returns the copy of the event the server returns, or an error. func (c *events) Create(event *api.Event) (*api.Event, error) { result := &api.Event{} - err := c.r.Post().Path("events").Body(event).Do().Into(result) + err := c.r.Post().Path("events").Namespace(event.Namespace).Body(event).Do().Into(result) return result, err } diff --git a/pkg/client/record/event.go b/pkg/client/record/event.go index 6d7f994b8b0..61c969cc543 100644 --- a/pkg/client/record/event.go +++ b/pkg/client/record/event.go @@ -29,6 +29,7 @@ import ( ) // EventRecorder knows how to store events (client.Client implements it.) +// EventRecorder must respect the namespace that will be embedded in 'event'. type EventRecorder interface { Create(event *api.Event) (*api.Event, error) } @@ -96,6 +97,8 @@ var events = watch.NewMux(queueLen) // handling of events, so imagine people writing switch statements to handle them. You want to // make that easy. // 'message' is intended to be human readable. +// +// The resulting event will be created in the same namespace as the reference object. func Event(object runtime.Object, fieldPath, status, reason, message string) { ref, err := api.GetReference(object) if err != nil { @@ -103,12 +106,18 @@ func Event(object runtime.Object, fieldPath, status, reason, message string) { return } ref.FieldPath = fieldPath + t := util.Now() + e := &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: fmt.Sprintf("%v.%x", ref.Name, t.UnixNano()), + Namespace: ref.Namespace, + }, InvolvedObject: *ref, Status: status, Reason: reason, Message: message, - Timestamp: util.Now(), + Timestamp: t, } events.Action(watch.Added, e) diff --git a/pkg/client/record/event_test.go b/pkg/client/record/event_test.go index bea85299db7..69ae0b31513 100644 --- a/pkg/client/record/event_test.go +++ b/pkg/client/record/event_test.go @@ -19,6 +19,7 @@ package record_test import ( "fmt" "reflect" + "strings" "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" @@ -55,9 +56,10 @@ func TestEventf(t *testing.T) { { obj: &api.Pod{ ObjectMeta: api.ObjectMeta{ - SelfLink: "/api/v1beta1/pods/foo", - Name: "foo", - UID: "bar", + SelfLink: "/api/v1beta1/pods/foo", + Name: "foo", + Namespace: "baz", + UID: "bar", }, }, fieldPath: "desiredState.manifest.containers[2]", @@ -66,9 +68,14 @@ func TestEventf(t *testing.T) { messageFmt: "some verbose message: %v", elements: []interface{}{1}, expect: &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: "baz", + }, InvolvedObject: api.ObjectReference{ Kind: "Pod", Name: "foo", + Namespace: "baz", UID: "bar", APIVersion: "v1beta1", FieldPath: "desiredState.manifest.containers[2]", @@ -78,7 +85,7 @@ func TestEventf(t *testing.T) { Message: "some verbose message: 1", Source: "eventTest", }, - expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"", Name:"foo", UID:"bar", APIVersion:"v1beta1", ResourceVersion:"", FieldPath:"desiredState.manifest.containers[2]"}): status: 'running', reason: 'started' some verbose message: 1`, + expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"v1beta1", ResourceVersion:"", FieldPath:"desiredState.manifest.containers[2]"}): status: 'running', reason: 'started' some verbose message: 1`, }, } @@ -92,6 +99,11 @@ func TestEventf(t *testing.T) { t.Errorf("timestamp wasn't set") } a.Timestamp = item.expect.Timestamp + // 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) + } + a.Name = item.expect.Name if e, a := item.expect, &a; !reflect.DeepEqual(e, a) { t.Errorf("diff: %s", util.ObjectDiff(e, a)) }