Merge pull request #2501 from xiaonancc77/master

Added ignore event types into notifications
This commit is contained in:
Derek McGowan 2018-03-14 10:37:02 -07:00 committed by GitHub
commit 607ae5d128
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 84 additions and 20 deletions

View File

@ -561,6 +561,13 @@ type Endpoint struct {
Threshold int `yaml:"threshold"` // circuit breaker threshold before backing off on failure
Backoff time.Duration `yaml:"backoff"` // backoff duration
IgnoredMediaTypes []string `yaml:"ignoredmediatypes"` // target media types to ignore
Ignore Ignore `yaml:"ignore"` // ignore event types
}
//Ignore configures mediaTypes and actions of the event, that it won't be propagated
type Ignore struct {
MediaTypes []string `yaml:"mediatypes"` // target media types to ignore
Actions []string `yaml:"actions"` // ignore action types
}
// Reporting defines error reporting methods.

View File

@ -63,6 +63,10 @@ var configStruct = Configuration{
"Authorization": []string{"Bearer <example>"},
},
IgnoredMediaTypes: []string{"application/octet-stream"},
Ignore: Ignore{
MediaTypes: []string{"application/octet-stream"},
Actions: []string{"pull"},
},
},
},
},
@ -148,6 +152,11 @@ notifications:
Authorization: [Bearer <example>]
ignoredmediatypes:
- application/octet-stream
ignore:
mediatypes:
- application/octet-stream
actions:
- pull
reporting:
bugsnag:
apikey: BugsnagApiKey
@ -176,6 +185,11 @@ notifications:
Authorization: [Bearer <example>]
ignoredmediatypes:
- application/octet-stream
ignore:
mediatypes:
- application/octet-stream
actions:
- pull
http:
headers:
X-Content-Type-Options: [nosniff]

View File

@ -236,6 +236,11 @@ notifications:
backoff: 1s
ignoredmediatypes:
- application/octet-stream
ignore:
mediatypes:
- application/octet-stream
actions:
- pull
redis:
addr: localhost:6379
password: asecret
@ -858,6 +863,11 @@ notifications:
backoff: 1s
ignoredmediatypes:
- application/octet-stream
ignore:
mediatypes:
- application/octet-stream
actions:
- pull
```
The notifications option is **optional** and currently may contain a single
@ -878,6 +888,14 @@ accept event notifications.
| `threshold` | yes | An integer specifying how long to wait before backing off a failure. |
| `backoff` | yes | How long the system backs off before retrying after a failure. A positive integer and an optional suffix indicating the unit of time, which may be `ns`, `us`, `ms`, `s`, `m`, or `h`. If you omit the unit of time, `ns` is used. |
| `ignoredmediatypes`|no| A list of target media types to ignore. Events with these target media types are not published to the endpoint. |
| `ignore` |no| Events with these mediatypes or actions are not published to the endpoint. |
#### `ignore`
| Parameter | Required | Description |
|-----------|----------|-------------------------------------------------------|
| `mediatypes`|no| A list of target media types to ignore. Events with these target media types are not published to the endpoint. |
| `actions` |no| A list of actions to ignore. Events with these actions are not published to the endpoint. |
## `redis`

View File

@ -1,6 +1,7 @@
package notifications
import (
"github.com/docker/distribution/configuration"
"net/http"
"time"
)
@ -14,6 +15,7 @@ type EndpointConfig struct {
Backoff time.Duration
IgnoredMediaTypes []string
Transport *http.Transport `json:"-"`
Ignore configuration.Ignore
}
// defaults set any zero-valued fields to a reasonable default.
@ -63,7 +65,8 @@ func NewEndpoint(name, url string, config EndpointConfig) *Endpoint {
endpoint.Transport, endpoint.metrics.httpStatusListener())
endpoint.Sink = newRetryingSink(endpoint.Sink, endpoint.Threshold, endpoint.Backoff)
endpoint.Sink = newEventQueue(endpoint.Sink, endpoint.metrics.eventQueueListener())
endpoint.Sink = newIgnoredMediaTypesSink(endpoint.Sink, config.IgnoredMediaTypes)
mediaTypes := append(config.Ignore.MediaTypes, config.IgnoredMediaTypes...)
endpoint.Sink = newIgnoredSink(endpoint.Sink, mediaTypes, config.Ignore.Actions)
register(&endpoint)
return &endpoint

View File

@ -210,14 +210,15 @@ func (eq *eventQueue) next() []Event {
return block
}
// ignoredMediaTypesSink discards events with ignored target media types and
// ignoredSink discards events with ignored target media types and actions.
// passes the rest along.
type ignoredMediaTypesSink struct {
type ignoredSink struct {
Sink
ignored map[string]bool
ignoreMediaTypes map[string]bool
ignoreActions map[string]bool
}
func newIgnoredMediaTypesSink(sink Sink, ignored []string) Sink {
func newIgnoredSink(sink Sink, ignored []string, ignoreActions []string) Sink {
if len(ignored) == 0 {
return sink
}
@ -227,25 +228,41 @@ func newIgnoredMediaTypesSink(sink Sink, ignored []string) Sink {
ignoredMap[mediaType] = true
}
return &ignoredMediaTypesSink{
ignoredActionsMap := make(map[string]bool)
for _, action := range ignoreActions {
ignoredActionsMap[action] = true
}
return &ignoredSink{
Sink: sink,
ignored: ignoredMap,
ignoreMediaTypes: ignoredMap,
ignoreActions: ignoredActionsMap,
}
}
// Write discards events with ignored target media types and passes the rest
// along.
func (imts *ignoredMediaTypesSink) Write(events ...Event) error {
func (imts *ignoredSink) Write(events ...Event) error {
var kept []Event
for _, e := range events {
if !imts.ignored[e.Target.MediaType] {
if !imts.ignoreMediaTypes[e.Target.MediaType] {
kept = append(kept, e)
}
}
if len(kept) == 0 {
return nil
}
return imts.Sink.Write(kept...)
var results []Event
for _, e := range kept {
if !imts.ignoreActions[e.Action] {
results = append(results, e)
}
}
if len(results) == 0 {
return nil
}
return imts.Sink.Write(results...)
}
// retryingSink retries the write until success or an ErrSinkClosed is

View File

@ -113,25 +113,29 @@ func TestEventQueue(t *testing.T) {
}
}
func TestIgnoredMediaTypesSink(t *testing.T) {
func TestIgnoredSink(t *testing.T) {
blob := createTestEvent("push", "library/test", "blob")
manifest := createTestEvent("push", "library/test", "manifest")
manifest := createTestEvent("pull", "library/test", "manifest")
type testcase struct {
ignored []string
ignoreMediaTypes []string
ignoreActions []string
expected []Event
}
cases := []testcase{
{nil, []Event{blob, manifest}},
{[]string{"other"}, []Event{blob, manifest}},
{[]string{"blob"}, []Event{manifest}},
{[]string{"blob", "manifest"}, nil},
{nil, nil, []Event{blob, manifest}},
{[]string{"other"}, []string{"other"}, []Event{blob, manifest}},
{[]string{"blob"}, []string{"other"}, []Event{manifest}},
{[]string{"blob", "manifest"}, []string{"other"}, nil},
{[]string{"other"}, []string{"push"}, []Event{manifest}},
{[]string{"other"}, []string{"pull"}, []Event{blob}},
{[]string{"other"}, []string{"pull", "push"}, nil},
}
for _, c := range cases {
ts := &testSink{}
s := newIgnoredMediaTypesSink(ts, c.ignored)
s := newIgnoredSink(ts, c.ignoreMediaTypes, c.ignoreActions)
if err := s.Write(blob, manifest); err != nil {
t.Fatalf("error writing event: %v", err)

View File

@ -450,6 +450,7 @@ func (app *App) configureEvents(configuration *configuration.Configuration) {
Backoff: endpoint.Backoff,
Headers: endpoint.Headers,
IgnoredMediaTypes: endpoint.IgnoredMediaTypes,
Ignore: endpoint.Ignore,
})
sinks = append(sinks, endpoint)