diff --git a/db/storage.go b/db/storage.go index 63c99fba05..fc624163f8 100644 --- a/db/storage.go +++ b/db/storage.go @@ -205,6 +205,7 @@ func (s *Storage) Limiter() *storage.Collection { func (s *Storage) Events() *storage.Collection { ownerIndex := mgo.Index{Key: []string{"owner.name"}} targetIndex := mgo.Index{Key: []string{"target.value"}} + extraTargetIndex := mgo.Index{Key: []string{"extratargets.target.value"}} kindIndex := mgo.Index{Key: []string{"kind.name"}} startTimeIndex := mgo.Index{Key: []string{"-starttime"}} uniqueIdIndex := mgo.Index{Key: []string{"uniqueid"}} @@ -212,6 +213,7 @@ func (s *Storage) Events() *storage.Collection { c := s.Collection("events") c.EnsureIndex(ownerIndex) c.EnsureIndex(targetIndex) + c.EnsureIndex(extraTargetIndex) c.EnsureIndex(kindIndex) c.EnsureIndex(startTimeIndex) c.EnsureIndex(uniqueIdIndex) diff --git a/event/event.go b/event/event.go index 4e7f8fc2b5..32b79415ac 100644 --- a/event/event.go +++ b/event/event.go @@ -447,6 +447,7 @@ func (f *Filter) LoadKindNames(form map[string][]string) { func (f *Filter) toQuery() (bson.M, error) { query := bson.M{} permMap := map[string][]permission.PermissionContext{} + andBlock := []bson.M{} if f.Permissions != nil { for _, p := range f.Permissions { permMap[p.Scheme.FullName()] = append(permMap[p.Scheme.FullName()], p.Context) @@ -472,27 +473,40 @@ func (f *Filter) toQuery() (bson.M, error) { } permOrBlock = append(permOrBlock, toAppend) } - query["$or"] = permOrBlock + andBlock = append(andBlock, bson.M{"$or": permOrBlock}) } if f.AllowedTargets != nil { var orBlock []bson.M for _, at := range f.AllowedTargets { f := bson.M{"target.type": at.Type} + extraF := bson.M{"extratargets.target.type": at.Type} if at.Values != nil { f["target.value"] = bson.M{"$in": at.Values} + extraF["extratargets.target.value"] = bson.M{"$in": at.Values} } - orBlock = append(orBlock, f) + orBlock = append(orBlock, f, extraF) } if len(orBlock) == 0 { return nil, errInvalidQuery } - query["$or"] = orBlock + andBlock = append(andBlock, bson.M{"$or": orBlock}) } if f.Target.Type != "" { - query["target.type"] = f.Target.Type + orBlock := []bson.M{ + {"target.type": f.Target.Type}, + {"extratargets.target.type": f.Target.Type}, + } + andBlock = append(andBlock, bson.M{"$or": orBlock}) } if f.Target.Value != "" { - query["target.value"] = f.Target.Value + orBlock := []bson.M{ + {"target.value": f.Target.Value}, + {"extratargets.target.value": f.Target.Value}, + } + andBlock = append(andBlock, bson.M{"$or": orBlock}) + } + if len(andBlock) > 0 { + query["$and"] = andBlock } if f.KindType != "" { query["kind.type"] = f.KindType diff --git a/event/eventlist_test.go b/event/eventlist_test.go index eacce664f3..68fd8e0fbc 100644 --- a/event/eventlist_test.go +++ b/event/eventlist_test.go @@ -62,7 +62,11 @@ func (s *S) TestListFilterMany(c *check.C) { c.Assert(evts, eventtest.EvtEquals, expected) } create(&event.Opts{ - Target: event.Target{Type: "app", Value: "myapp"}, + Target: event.Target{Type: "app", Value: "myapp"}, + ExtraTargets: []event.ExtraTarget{ + {Target: event.Target{Type: "app", Value: "xapp1"}}, + {Target: event.Target{Type: "app", Value: "xapp2"}}, + }, Kind: permission.PermAppUpdateEnvSet, Owner: s.token, Allowed: event.Allowed(permission.PermAppReadEvents, permission.Context(permission.CtxApp, "myapp")), @@ -110,6 +114,8 @@ func (s *S) TestListFilterMany(c *check.C) { checkFilters(&event.Filter{ErrorOnly: true, Sort: "_id"}, allEvts[len(allEvts)-3]) checkFilters(&event.Filter{Target: event.Target{Type: "app"}, Sort: "_id"}, []*event.Event{allEvts[0], allEvts[1]}) checkFilters(&event.Filter{Target: event.Target{Type: "app", Value: "myapp"}}, allEvts[0]) + checkFilters(&event.Filter{Target: event.Target{Type: "app", Value: "xapp1"}}, allEvts[0]) + checkFilters(&event.Filter{Target: event.Target{Type: "app", Value: "xapp2"}}, allEvts[0]) checkFilters(&event.Filter{KindType: event.KindTypeInternal, Sort: "_id"}, allEvts[3:len(allEvts)-1]) checkFilters(&event.Filter{KindType: event.KindTypePermission, Sort: "_id"}, allEvts[:3]) checkFilters(&event.Filter{KindType: event.KindTypePermission, KindNames: []string{"kind"}}, nil) @@ -138,6 +144,12 @@ func (s *S) TestListFilterMany(c *check.C) { {Type: "app", Values: []string{"myapp"}}, {Type: "node", Values: []string{"http://10.0.1.2"}}, }, Sort: "_id"}, []*event.Event{allEvts[0], allEvts[4]}) + checkFilters(&event.Filter{AllowedTargets: []event.TargetFilter{ + {Type: "app", Values: []string{"xapp1", "myapp2"}}, + }, Sort: "_id"}, allEvts[:2]) + checkFilters(&event.Filter{AllowedTargets: []event.TargetFilter{ + {Type: "app", Values: []string{"xapp2"}}, + }, Sort: "_id"}, allEvts[0]) checkFilters(&event.Filter{Permissions: []permission.Permission{ {Scheme: permission.PermAll, Context: permission.Context(permission.CtxGlobal, "")}, }, Sort: "_id"}, allEvts[:len(allEvts)-1])