consul: Support conditional policy fetch

This commit is contained in:
Armon Dadgar 2014-08-08 16:55:47 -07:00
parent 45f358e715
commit b5e22203fc
4 changed files with 41 additions and 5 deletions

View File

@ -69,7 +69,7 @@ func (s *Server) lookupACL(id, authDC string) (acl.ACL, error) {
}
// Attempt to refresh the policy
args := structs.ACLSpecificRequest{
args := structs.ACLPolicyRequest{
Datacenter: authDC,
ACL: id,
}

View File

@ -88,7 +88,7 @@ func (a *ACL) Get(args *structs.ACLSpecificRequest,
// GetPolicy is used to retrieve a compiled policy object with a TTL. Does not
// support a blocking query.
func (a *ACL) GetPolicy(args *structs.ACLSpecificRequest, reply *structs.ACLPolicy) error {
func (a *ACL) GetPolicy(args *structs.ACLPolicyRequest, reply *structs.ACLPolicy) error {
if done, err := a.srv.forward("ACL.GetPolicy", args, args, reply); done {
return err
}
@ -99,12 +99,20 @@ func (a *ACL) GetPolicy(args *structs.ACLSpecificRequest, reply *structs.ACLPoli
return err
}
// Setup the response
// Generate an ETag
conf := a.srv.config
reply.Policy = policy
etag := fmt.Sprintf("%s:%s", conf.ACLDefaultPolicy, policy.ID)
// Setup the response
reply.ETag = etag
reply.Root = conf.ACLDefaultPolicy
reply.TTL = conf.ACLTTL
a.srv.setQueryMeta(&reply.QueryMeta)
// Only send the policy on an Etag mis-match
if args.ETag != etag {
reply.Policy = policy
}
return nil
}

View File

@ -130,7 +130,7 @@ func TestACLEndpoint_GetPolicy(t *testing.T) {
t.Fatalf("err: %v", err)
}
getR := structs.ACLSpecificRequest{
getR := structs.ACLPolicyRequest{
Datacenter: "dc1",
ACL: out,
}
@ -145,6 +145,20 @@ func TestACLEndpoint_GetPolicy(t *testing.T) {
if acls.TTL != 30*time.Second {
t.Fatalf("bad: %v", acls)
}
// Do a conditional lookup with etag
getR.ETag = acls.ETag
var out2 structs.ACLPolicy
if err := client.Call("ACL.GetPolicy", &getR, &out2); err != nil {
t.Fatalf("err: %v", err)
}
if out2.Policy != nil {
t.Fatalf("Bad: %v", out2)
}
if out2.TTL != 30*time.Second {
t.Fatalf("bad: %v", out2)
}
}
func TestACLEndpoint_List(t *testing.T) {

View File

@ -466,12 +466,26 @@ func (r *ACLSpecificRequest) RequestDatacenter() string {
return r.Datacenter
}
// ACLPolicyRequest is used to request an ACL by ID, conditionally
// filtering on an ID
type ACLPolicyRequest struct {
Datacenter string
ACL string
ETag string
QueryOptions
}
func (r *ACLPolicyRequest) RequestDatacenter() string {
return r.Datacenter
}
type IndexedACLs struct {
ACLs ACLs
QueryMeta
}
type ACLPolicy struct {
ETag string
Root string
Policy *acl.Policy
TTL time.Duration