consul: Helpers to filter on ACL rules

This commit is contained in:
Armon Dadgar 2014-08-13 10:42:10 -07:00
parent 84488ed1f0
commit 614b0a1414
2 changed files with 104 additions and 0 deletions

39
consul/filter.go Normal file
View File

@ -0,0 +1,39 @@
package consul
import (
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/consul/structs"
)
func FilterDirEnt(acl acl.ACL, ent structs.DirEntries) structs.DirEntries {
// Remove any keys blocked by ACLs
removed := 0
for i := 0; i < len(ent); i++ {
if !acl.KeyRead(ent[i].Key) {
ent[i] = nil
removed++
}
}
// Compact the list
dst := 0
src := 0
n := len(ent) - removed
for dst < n {
for ent[src] == nil && src < n {
src++
}
end := src + 1
for ent[end] != nil && end < n {
end++
}
span := end - src
copy(ent[dst:dst+span], ent[src:src+span])
dst += span
src += span
}
// Trim the entries
ent = ent[:n]
return ent
}

65
consul/filter_test.go Normal file
View File

@ -0,0 +1,65 @@
package consul
import (
"reflect"
"testing"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/consul/structs"
)
func TestFilterDirEnt(t *testing.T) {
policy, _ := acl.Parse(testFilterRules)
aclR, _ := acl.New(acl.DenyAll(), policy)
type tcase struct {
in []string
out []string
}
cases := []tcase{
tcase{
in: []string{"foo/test", "foo/priv/nope", "foo/other", "zoo"},
out: []string{"foo/test", "foo/other"},
},
tcase{
in: []string{"abe", "lincoln"},
out: nil,
},
tcase{
in: []string{"abe", "foo/1", "foo/2", "foo/3", "nope"},
out: []string{"foo/1", "foo/2", "foo/3"},
},
}
for _, tc := range cases {
ents := structs.DirEntries{}
for _, in := range tc.in {
ents = append(ents, &structs.DirEntry{Key: in})
}
ents = FilterDirEnt(aclR, ents)
var outL []string
for _, e := range ents {
outL = append(outL, e.Key)
}
if !reflect.DeepEqual(outL, tc.out) {
t.Fatalf("bad: %#v %#v", outL, tc.out)
}
}
}
var testFilterRules = `
key "" {
policy = "deny"
}
key "foo/" {
policy = "read"
}
key "foo/priv/" {
policy = "deny"
}
key "zip/" {
policy = "read"
}
`