events: autogenerate fieldpath filters

To ensure consistent fieldpath matching for events, we generate the
fieldpath matching using protobuf definitions. This is done through a
plugin called "fieldpath" that defines a `Field` method for each type
with the plugin enabled. Generated code handles top-level envelope
fields, as well as deferred serialization for matching any types.

In practice, this means that we can cheaply match events on `topic` and
`namespace`. If we want to match on attributes within the event, we can
use the `event` prefix to address these fields. For example, the
following will match all envelopes that have a field named
`container_id` that has the value `testing`:

```
ctr events "event.container_id==testing"
```

The above will decode the underlying event and check that particular
field. Accordingly, if only `topic` or `namespace` is used, the event
will not be decoded and only match on the envelope.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
Stephen J Day
2017-07-31 19:14:39 -07:00
parent bb7b41ad7b
commit c857ba2d0b
24 changed files with 1005 additions and 215 deletions

View File

@@ -219,25 +219,8 @@ func validateEnvelope(envelope *events.Envelope) error {
}
func adapt(ev interface{}) filters.Adaptor {
switch ev := ev.(type) {
case *events.Envelope:
return filters.AdapterFunc(func(fieldpath []string) (string, bool) {
if len(fieldpath) == 0 {
return "", false
}
switch fieldpath[0] {
case "namespace":
return ev.Namespace, len(ev.Namespace) > 0
case "topic":
return ev.Topic, len(ev.Topic) > 0
default:
// TODO(stevvooe): Handle event fields.
return "", false
}
})
case filters.Adaptor:
return ev
if adaptor, ok := ev.(filters.Adaptor); ok {
return adaptor
}
return filters.AdapterFunc(func(fieldpath []string) (string, bool) {