Event notification message definition
This commit defines the message format used to notify external parties of activity within a registry instance. The event includes information about which action was taken on which registry object, including what user created the action and which instance generated the event. Message instances can be sent throughout an application or transmitted externally. An envelope format along with a custom media type is defined along with tests to detect changes to the wire format. Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
parent
092dadde6d
commit
af7eb42793
2 changed files with 253 additions and 0 deletions
131
storage/notifications/event_test.go
Normal file
131
storage/notifications/event_test.go
Normal file
|
@ -0,0 +1,131 @@
|
|||
package notifications
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestEventJSONFormat provides silly test to detect if the event format or
|
||||
// envelope has changed. If this code fails, the revision of the protocol may
|
||||
// need to be incremented.
|
||||
func TestEventEnvelopeJSONFormat(t *testing.T) {
|
||||
var expected = strings.TrimSpace(`
|
||||
{
|
||||
"events": [
|
||||
{
|
||||
"uuid": "asdf-asdf-asdf-asdf-0",
|
||||
"timestamp": "2006-01-02T15:04:05Z",
|
||||
"action": "push",
|
||||
"target": {
|
||||
"type": "manifest",
|
||||
"name": "library/test",
|
||||
"digest": "sha256:0123456789abcdef0",
|
||||
"tag": "latest",
|
||||
"url": "http://example.com/v2/library/test/manifests/latest"
|
||||
},
|
||||
"actor": {
|
||||
"name": "test-actor",
|
||||
"addr": "hostname.local"
|
||||
},
|
||||
"source": {
|
||||
"addr": "hostname.local",
|
||||
"host": "registrycluster.local",
|
||||
"request_id": "asdfasdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "asdf-asdf-asdf-asdf-1",
|
||||
"timestamp": "2006-01-02T15:04:05Z",
|
||||
"action": "push",
|
||||
"target": {
|
||||
"type": "blob",
|
||||
"name": "library/test",
|
||||
"digest": "tarsum.v2+sha256:0123456789abcdef1",
|
||||
"url": "http://example.com/v2/library/test/manifests/latest"
|
||||
},
|
||||
"actor": {
|
||||
"name": "test-actor",
|
||||
"addr": "hostname.local"
|
||||
},
|
||||
"source": {
|
||||
"addr": "hostname.local",
|
||||
"host": "registrycluster.local",
|
||||
"request_id": "asdfasdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "asdf-asdf-asdf-asdf-2",
|
||||
"timestamp": "2006-01-02T15:04:05Z",
|
||||
"action": "push",
|
||||
"target": {
|
||||
"type": "blob",
|
||||
"name": "library/test",
|
||||
"digest": "tarsum.v2+sha256:0123456789abcdef2",
|
||||
"url": "http://example.com/v2/library/test/manifests/latest"
|
||||
},
|
||||
"actor": {
|
||||
"name": "test-actor",
|
||||
"addr": "hostname.local"
|
||||
},
|
||||
"source": {
|
||||
"addr": "hostname.local",
|
||||
"host": "registrycluster.local",
|
||||
"request_id": "asdfasdf"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
`)
|
||||
|
||||
tm, err := time.Parse(time.RFC3339, time.RFC3339[:len(time.RFC3339)-5])
|
||||
if err != nil {
|
||||
t.Fatalf("error creating time: %v", err)
|
||||
}
|
||||
|
||||
var prototype Event
|
||||
prototype.Action = "push"
|
||||
prototype.Timestamp = tm
|
||||
prototype.Actor.Addr = "hostname.local"
|
||||
prototype.Actor.Name = "test-actor"
|
||||
prototype.Source.Addr = "hostname.local"
|
||||
prototype.Source.Host = "registrycluster.local"
|
||||
prototype.Source.RequestID = "asdfasdf"
|
||||
|
||||
var manifestPush Event
|
||||
manifestPush = prototype
|
||||
manifestPush.ID = "asdf-asdf-asdf-asdf-0"
|
||||
manifestPush.Target.Digest = "sha256:0123456789abcdef0"
|
||||
manifestPush.Target.Type = "manifest"
|
||||
manifestPush.Target.Name = "library/test"
|
||||
manifestPush.Target.Tag = "latest"
|
||||
manifestPush.Target.URL = "http://example.com/v2/library/test/manifests/latest"
|
||||
|
||||
var layerPush0 Event
|
||||
layerPush0 = prototype
|
||||
layerPush0.ID = "asdf-asdf-asdf-asdf-1"
|
||||
layerPush0.Target.Digest = "tarsum.v2+sha256:0123456789abcdef1"
|
||||
layerPush0.Target.Type = "blob"
|
||||
layerPush0.Target.Name = "library/test"
|
||||
layerPush0.Target.URL = "http://example.com/v2/library/test/manifests/latest"
|
||||
|
||||
var layerPush1 Event
|
||||
layerPush1 = prototype
|
||||
layerPush1.ID = "asdf-asdf-asdf-asdf-2"
|
||||
layerPush1.Target.Digest = "tarsum.v2+sha256:0123456789abcdef2"
|
||||
layerPush1.Target.Type = "blob"
|
||||
layerPush1.Target.Name = "library/test"
|
||||
layerPush1.Target.URL = "http://example.com/v2/library/test/manifests/latest"
|
||||
|
||||
var envelope Envelope
|
||||
envelope.Events = append(envelope.Events, manifestPush, layerPush0, layerPush1)
|
||||
|
||||
p, err := json.MarshalIndent(envelope, "", " ")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error marshaling envelope: %v", err)
|
||||
}
|
||||
if string(p) != expected {
|
||||
t.Fatalf("format has changed\n%s\n != \n%s", string(p), expected)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue