Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix legacy management tokens in unupgraded secondary dcs #7908

Merged
merged 1 commit into from
Jun 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions agent/consul/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -1154,16 +1154,17 @@ func (r *ACLResolver) ACLsEnabled() bool {
return true
}

func (r *ACLResolver) GetMergedPolicyForToken(token string) (*acl.Policy, error) {
policies, err := r.resolveTokenToPolicies(token)
func (r *ACLResolver) GetMergedPolicyForToken(token string) (structs.ACLIdentity, *acl.Policy, error) {
ident, policies, err := r.resolveTokenToIdentityAndPolicies(token)
if err != nil {
return nil, err
return nil, nil, err
}
if len(policies) == 0 {
return nil, acl.ErrNotFound
return nil, nil, acl.ErrNotFound
}

return policies.Merge(r.cache, r.aclConf)
policy, err := policies.Merge(r.cache, r.aclConf)
return ident, policy, err
}

// aclFilter is used to filter results from our state store based on ACL rules
Expand Down
6 changes: 5 additions & 1 deletion agent/consul/acl_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -1324,11 +1324,15 @@ func (a *ACL) GetPolicy(args *structs.ACLPolicyResolveLegacyRequest, reply *stru
// Get the policy via the cache
parent := a.srv.config.ACLDefaultPolicy

policy, err := a.srv.acls.GetMergedPolicyForToken(args.ACL)
ident, policy, err := a.srv.acls.GetMergedPolicyForToken(args.ACL)
if err != nil {
return err
}

if token, ok := ident.(*structs.ACLToken); ok && token.Type == structs.ACLTokenTypeManagement {
parent = "manage"
mkeeler marked this conversation as resolved.
Show resolved Hide resolved
}

// translates the structures internals to most closely match what could be expressed in the original rule language
policy = policy.ConvertToLegacy()

Expand Down
54 changes: 32 additions & 22 deletions agent/consul/acl_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ func TestACLEndpoint_GetPolicy(t *testing.T) {
c.ACLDatacenter = "dc1"
c.ACLsEnabled = true
c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
Expand All @@ -471,9 +472,7 @@ func TestACLEndpoint_GetPolicy(t *testing.T) {
WriteRequest: structs.WriteRequest{Token: "root"},
}
var out string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
t.Fatalf("err: %v", err)
}
require.NoError(t, msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out))

getR := structs.ACLPolicyResolveLegacyRequest{
Datacenter: "dc1",
Expand All @@ -482,32 +481,43 @@ func TestACLEndpoint_GetPolicy(t *testing.T) {

var acls structs.ACLPolicyResolveLegacyResponse
retry.Run(t, func(r *retry.R) {

if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicy", &getR, &acls); err != nil {
r.Fatalf("err: %v", err)
}

if acls.Policy == nil {
r.Fatalf("Bad: %v", acls)
}
if acls.TTL != 30*time.Second {
r.Fatalf("bad: %v", acls)
}
require.NoError(r, msgpackrpc.CallWithCodec(codec, "ACL.GetPolicy", &getR, &acls))
require.NotNil(t, acls.Policy)
require.Equal(t, "deny", acls.Parent)
require.Equal(t, 30*time.Second, acls.TTL)
})

// Do a conditional lookup with etag
getR.ETag = acls.ETag
var out2 structs.ACLPolicyResolveLegacyResponse
if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicy", &getR, &out2); err != nil {
t.Fatalf("err: %v", err)
}
require.NoError(t, msgpackrpc.CallWithCodec(codec, "ACL.GetPolicy", &getR, &out2))

if out2.Policy != nil {
t.Fatalf("Bad: %v", out2)
}
if out2.TTL != 30*time.Second {
t.Fatalf("bad: %v", out2)
require.Nil(t, out2.Policy)
require.Equal(t, 30*time.Second, out2.TTL)
}

func TestACLEndpoint_GetPolicy_Management(t *testing.T) {
t.Parallel()
dir1, s1 := testServerWithConfig(t, testServerACLConfig(nil))
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
defer codec.Close()

// wait for leader election and leader establishment to finish.
// after this the global management policy, master token and
// anonymous token will have been injected into the state store
// and we will be ready to resolve the master token
waitForLeaderEstablishment(t, s1)

req := structs.ACLPolicyResolveLegacyRequest{
Datacenter: s1.config.Datacenter,
ACL: TestDefaultMasterToken,
}

var resp structs.ACLPolicyResolveLegacyResponse
require.NoError(t, msgpackrpc.CallWithCodec(codec, "ACL.GetPolicy", &req, &resp))
require.Equal(t, "manage", resp.Parent)
}

func TestACLEndpoint_List(t *testing.T) {
Expand Down