structs: sort policies to avoid order dependence for caching

This commit is contained in:
Armon Dadgar
2017-08-20 16:07:00 -07:00
parent 5b43ea4bff
commit 00833d69c4
2 changed files with 27 additions and 0 deletions

View File

@@ -6,6 +6,7 @@ import (
"encoding/binary"
"fmt"
"math"
"sort"
"strings"
multierror "github.com/hashicorp/go-multierror"
@@ -273,6 +274,9 @@ func ACLPolicyListHash(policies []*ACLPolicy) string {
// CompileACLObject compiles a set of ACL policies into an ACL object with a cache
func CompileACLObject(cache *lru.TwoQueueCache, policies []*ACLPolicy) (*acl.ACL, error) {
// Sort the policies to ensure consistent ordering
sort.Sort(ACLPolicyList(policies))
// Determine the cache key
cacheKey := ACLPolicyListHash(policies)
aclRaw, ok := cache.Get(cacheKey)
@@ -300,3 +304,18 @@ func CompileACLObject(cache *lru.TwoQueueCache, policies []*ACLPolicy) (*acl.ACL
cache.Add(cacheKey, aclObj)
return aclObj, nil
}
// ACLPolicyList is used to sort a set of policies by name
type ACLPolicyList []*ACLPolicy
func (l ACLPolicyList) Len() int {
return len(l)
}
func (l ACLPolicyList) Swap(i, j int) {
l[i], l[j] = l[j], l[i]
}
func (l ACLPolicyList) Less(i, j int) bool {
return l[i].Name < l[j].Name
}

View File

@@ -366,4 +366,12 @@ func TestCompileACLObject(t *testing.T) {
if aclObj == aclObj3 {
t.Fatalf("unexpected same object")
}
// Should be order independent
aclObj4, err := CompileACLObject(cache, []*ACLPolicy{p2, p1})
assert.Nil(t, err)
assert.NotNil(t, aclObj4)
if aclObj3 != aclObj4 {
t.Fatalf("expected same object")
}
}