Merge pull request #10986 from hashicorp/dnephin/acl-legacy-remove-rpc

acl: remove legacy ACL RPC - part 1
This commit is contained in:
Daniel Nephin 2021-09-29 12:04:09 -04:00 committed by GitHub
commit acb62aa896
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 252 additions and 1299 deletions

View File

@ -6,10 +6,8 @@ import (
"github.com/armon/go-metrics"
"github.com/armon/go-metrics/prometheus"
"github.com/hashicorp/go-memdb"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/consul/state"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/lib"
)
@ -141,94 +139,10 @@ func (a *ACL) Apply(args *structs.ACLRequest, reply *string) error {
return nil
}
// Get is used to retrieve a single ACL
func (a *ACL) Get(args *structs.ACLSpecificRequest,
reply *structs.IndexedACLs) error {
if done, err := a.srv.ForwardRPC("ACL.Get", args, reply); done {
return err
}
// NOTE: This has no ACL check because legacy ACLs were managed with
// the secrets and therefore the argument to the Get request is
// authorization in and of itself.
// Verify we are allowed to serve this request
if !a.srv.config.ACLsEnabled {
return acl.ErrDisabled
}
return a.srv.blockingQuery(&args.QueryOptions,
&reply.QueryMeta,
func(ws memdb.WatchSet, state *state.Store) error {
index, token, err := state.ACLTokenGetBySecret(ws, args.ACL, nil)
if err != nil {
return err
}
// Converting an ACLToken to an ACL will return nil and an error
// (which we ignore) when it is unconvertible.
//
// This also means we won't have to check expiration times since
// any legacy tokens never had expiration times and no non-legacy
// tokens can be converted.
var acl *structs.ACL
if token != nil {
acl, _ = token.Convert()
}
reply.Index = index
if acl != nil {
reply.ACLs = structs.ACLs{acl}
} else {
reply.ACLs = nil
}
return nil
})
func (a *ACL) Get(*structs.ACLSpecificRequest, *structs.IndexedACLs) error {
return fmt.Errorf("ACL.Get: the legacy ACL system has been removed")
}
// List is used to list all the ACLs
func (a *ACL) List(args *structs.DCSpecificRequest,
reply *structs.IndexedACLs) error {
if done, err := a.srv.ForwardRPC("ACL.List", args, reply); done {
return err
}
// Verify we are allowed to serve this request
if !a.srv.config.ACLsEnabled {
return acl.ErrDisabled
}
// Verify token is permitted to list ACLs
// NOTES: Previously with legacy ACL there was no read-only ACL permissions
// and this check for ACLWrite is basically what it did before.
if authz, err := a.srv.ResolveToken(args.Token); err != nil {
return err
} else if authz.ACLWrite(nil) != acl.Allow {
return acl.ErrPermissionDenied
}
return a.srv.blockingQuery(&args.QueryOptions,
&reply.QueryMeta,
func(ws memdb.WatchSet, state *state.Store) error {
index, tokens, err := state.ACLTokenList(ws, false, true, "", "", "", nil, nil)
if err != nil {
return err
}
now := time.Now()
var acls structs.ACLs
for _, token := range tokens {
if token.IsExpired(now) {
continue
}
if acl, err := token.Convert(); err == nil && acl != nil {
acls = append(acls, acl)
}
}
reply.Index, reply.ACLs = index, acls
return nil
})
func (a *ACL) List(*structs.DCSpecificRequest, *structs.IndexedACLs) error {
return fmt.Errorf("ACL.List: the legacy ACL system has been removed")
}

View File

@ -275,40 +275,6 @@ func TestACLEndpoint_Apply_RootChange(t *testing.T) {
testutil.RequireErrorContains(t, err, "root ACL")
}
func TestACLEndpoint_Get(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
}
t.Parallel()
_, srv, codec := testACLServerWithConfig(t, nil, false)
waitForLeaderEstablishment(t, srv)
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
},
WriteRequest: structs.WriteRequest{Token: TestDefaultMasterToken},
}
var out string
err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out)
require.NoError(t, err)
getR := structs.ACLSpecificRequest{
Datacenter: "dc1",
ACL: out,
}
var acls structs.IndexedACLs
err = msgpackrpc.CallWithCodec(codec, "ACL.Get", &getR, &acls)
require.NoError(t, err)
require.NotEqual(t, uint64(0), acls.Index)
require.Len(t, acls.ACLs, 1)
require.Equal(t, out, acls.ACLs[0].ID)
}
func TestACLEndpoint_GetPolicy(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
@ -378,75 +344,6 @@ func TestACLEndpoint_GetPolicy_Management(t *testing.T) {
require.Equal(t, "manage", resp.Parent)
}
func TestACLEndpoint_List(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
}
t.Parallel()
_, srv, codec := testACLServerWithConfig(t, nil, false)
waitForLeaderEstablishment(t, srv)
var expectedIDs []string
for i := 0; i < 5; i++ {
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
},
WriteRequest: structs.WriteRequest{Token: TestDefaultMasterToken},
}
var out string
err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out)
require.NoError(t, err)
expectedIDs = append(expectedIDs, out)
}
getR := structs.DCSpecificRequest{
Datacenter: "dc1",
QueryOptions: structs.QueryOptions{Token: TestDefaultMasterToken},
}
var acls structs.IndexedACLs
err := msgpackrpc.CallWithCodec(codec, "ACL.List", &getR, &acls)
require.NoError(t, err)
require.NotEqual(t, uint64(0), acls.Index)
// 5 + master
require.Len(t, acls.ACLs, 6)
var actualIDs []string
for i := 0; i < len(acls.ACLs); i++ {
s := acls.ACLs[i]
if s.ID == anonymousToken || s.ID == TestDefaultMasterToken {
continue
}
require.Equal(t, "User token", s.Name)
actualIDs = append(actualIDs, s.ID)
}
require.ElementsMatch(t, expectedIDs, actualIDs)
}
func TestACLEndpoint_List_Denied(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
}
t.Parallel()
_, srv, codec := testACLServerWithConfig(t, nil, false)
waitForLeaderEstablishment(t, srv)
getR := structs.DCSpecificRequest{
Datacenter: "dc1",
}
var acls structs.IndexedACLs
err := msgpackrpc.CallWithCodec(codec, "ACL.List", &getR, &acls)
require.True(t, acl.IsErrPermissionDenied(err), "Err %v is not an acl.ErrPermissionDenied", err)
}
func TestACLEndpoint_ReplicationStatus(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")

View File

@ -2501,189 +2501,6 @@ func TestACLResolver_Legacy(t *testing.T) {
})
})
}
/*
func TestACL_Replication(t *testing.T) {
t.Parallel()
aclExtendPolicies := []string{"extend-cache", "async-cache"} //"async-cache"
for _, aclDownPolicy := range aclExtendPolicies {
dir1, s1 := testServerWithConfig(t, func(c *Config) {
c.PrimaryDatacenter = "dc1"
c.ACLMasterToken = "root"
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
client := rpcClient(t, s1)
defer client.Close()
dir2, s2 := testServerWithConfig(t, func(c *Config) {
c.Datacenter = "dc2"
c.PrimaryDatacenter = "dc1"
c.ACLResolverSettings.ACLDefaultPolicy = "deny"
c.ACLDownPolicy = aclDownPolicy
c.ACLTokenReplication = true
c.ACLReplicationRate = 100
c.ACLReplicationBurst = 100
c.ACLReplicationApplyLimit = 1000000
})
s2.tokens.UpdateReplicationToken("root")
defer os.RemoveAll(dir2)
defer s2.Shutdown()
dir3, s3 := testServerWithConfig(t, func(c *Config) {
c.Datacenter = "dc3"
c.PrimaryDatacenter = "dc1"
c.ACLDownPolicy = "deny"
c.ACLTokenReplication = true
c.ACLReplicationRate = 100
c.ACLReplicationBurst = 100
c.ACLReplicationApplyLimit = 1000000
})
s3.tokens.UpdateReplicationToken("root")
defer os.RemoveAll(dir3)
defer s3.Shutdown()
// Try to join.
joinWAN(t, s2, s1)
joinWAN(t, s3, s1)
testrpc.WaitForLeader(t, s1.RPC, "dc1")
testrpc.WaitForLeader(t, s1.RPC, "dc2")
testrpc.WaitForLeader(t, s1.RPC, "dc3")
// Create a new token.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: testACLPolicy,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := s1.RPC("ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
// Wait for replication to occur.
retry.Run(t, func(r *retry.R) {
_, acl, err := s2.fsm.State().ACLTokenGetBySecret(nil, id)
if err != nil {
r.Fatal(err)
}
if acl == nil {
r.Fatal(nil)
}
_, acl, err = s3.fsm.State().ACLTokenGetBySecret(nil, id)
if err != nil {
r.Fatal(err)
}
if acl == nil {
r.Fatal(nil)
}
})
// Kill the ACL datacenter.
s1.Shutdown()
// Token should resolve on s2, which has replication + extend-cache.
acl, err := s2.ResolveToken(id)
if err != nil {
t.Fatalf("err: %v", err)
}
if acl == nil {
t.Fatalf("missing acl")
}
// Check the policy
if acl.KeyRead("bar") {
t.Fatalf("unexpected read")
}
if !acl.KeyRead("foo/test") {
t.Fatalf("unexpected failed read")
}
// Although s3 has replication, and we verified that the ACL is there,
// it can not be used because of the down policy.
acl, err = s3.ResolveToken(id)
if err != nil {
t.Fatalf("err: %v", err)
}
if acl == nil {
t.Fatalf("missing acl")
}
// Check the policy.
if acl.KeyRead("bar") {
t.Fatalf("unexpected read")
}
if acl.KeyRead("foo/test") {
t.Fatalf("unexpected read")
}
}
}
func TestACL_MultiDC_Found(t *testing.T) {
t.Parallel()
dir1, s1 := testServerWithConfig(t, func(c *Config) {
c.PrimaryDatacenter = "dc1"
c.ACLMasterToken = "root"
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
client := rpcClient(t, s1)
defer client.Close()
dir2, s2 := testServerWithConfig(t, func(c *Config) {
c.Datacenter = "dc2"
c.PrimaryDatacenter = "dc1" // Enable ACLs!
})
defer os.RemoveAll(dir2)
defer s2.Shutdown()
// Try to join
joinWAN(t, s2, s1)
testrpc.WaitForLeader(t, s1.RPC, "dc1")
testrpc.WaitForLeader(t, s1.RPC, "dc2")
// Create a new token
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: testACLPolicy,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := s1.RPC("ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
// Token should resolve
acl, err := s2.ResolveToken(id)
if err != nil {
t.Fatalf("err: %v", err)
}
if acl == nil {
t.Fatalf("missing acl")
}
// Check the policy
if acl.KeyRead("bar") {
t.Fatalf("unexpected read")
}
if !acl.KeyRead("foo/test") {
t.Fatalf("unexpected failed read")
}
}
*/
func TestACL_filterHealthChecks(t *testing.T) {
t.Parallel()
// Create some health checks.

View File

@ -8,6 +8,8 @@ import (
"testing"
"time"
"github.com/hashicorp/go-uuid"
msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -191,28 +193,15 @@ func TestCatalog_Register_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1)
defer codec.Close()
// Create the ACL.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
service "foo" {
policy = "write"
}
node "foo" {
policy = "write"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
`
id := createToken(t, codec, rules)
argR := structs.RegisterRequest{
Datacenter: "dc1",
@ -272,6 +261,41 @@ node "foo" {
}
}
func createToken(t *testing.T, cc rpc.ClientCodec, policyRules string) string {
t.Helper()
return createTokenWithPolicyName(t, "the-policy", cc, policyRules)
}
func createTokenWithPolicyName(t *testing.T, policyName string, cc rpc.ClientCodec, policyRules string) string {
t.Helper()
reqPolicy := structs.ACLPolicySetRequest{
Datacenter: "dc1",
Policy: structs.ACLPolicy{
Name: policyName,
Rules: policyRules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
err := msgpackrpc.CallWithCodec(cc, "ACL.PolicySet", &reqPolicy, &structs.ACLPolicy{})
require.NoError(t, err)
token, err := uuid.GenerateUUID()
require.NoError(t, err)
reqToken := structs.ACLTokenSetRequest{
Datacenter: "dc1",
ACLToken: structs.ACLToken{
SecretID: token,
Policies: []structs.ACLTokenPolicyLink{{Name: policyName}},
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
err = msgpackrpc.CallWithCodec(cc, "ACL.TokenSet", &reqToken, &structs.ACLToken{})
require.NoError(t, err)
return token
}
func TestCatalog_Register_ForwardLeader(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
@ -438,26 +462,15 @@ func TestCatalog_Register_ConnectProxy_ACLDestinationServiceName(t *testing.T) {
testrpc.WaitForLeader(t, s1.RPC, "dc1")
// Create the ACL.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
service "foo" {
policy = "write"
}
node "foo" {
policy = "write"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var token string
assert.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &token))
`
token := createToken(t, codec, rules)
// Register should fail because we don't have permission on the destination
args := structs.TestRegisterRequestProxy(t)
@ -567,14 +580,7 @@ func TestCatalog_Deregister_ACLDeny(t *testing.T) {
testrpc.WaitForLeader(t, s1.RPC, "dc1")
// Create the ACL.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
node "node" {
policy = "write"
}
@ -582,14 +588,8 @@ node "node" {
service "service" {
policy = "write"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
`
id := createToken(t, codec, rules)
// Register a node, node check, service, and service check.
argR := structs.RegisterRequest{
@ -1325,25 +1325,12 @@ func TestCatalog_ListNodes_ACLFilter(t *testing.T) {
}
}
// Create an ACL that can read the node.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: fmt.Sprintf(`
rules := fmt.Sprintf(`
node "%s" {
policy = "read"
}
`, s1.config.NodeName),
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
`, s1.config.NodeName)
id := createToken(t, codec, rules)
// Now try with the token and it will go through.
args.Token = id
@ -2425,24 +2412,18 @@ func TestCatalog_ListServiceNodes_ConnectProxy_ACL(t *testing.T) {
testrpc.WaitForLeader(t, s1.RPC, "dc1")
// Create the ACL.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
service "foo-proxy" {
policy = "write"
}
service "foo" {
policy = "write"
}
node "" { policy = "read" }
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var token string
require.NoError(t, msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &token))
node "foo" {
policy = "read"
}
`
token := createToken(t, codec, rules)
{
// Register a proxy
@ -2717,27 +2698,15 @@ func testACLFilterServer(t *testing.T) (dir, token string, srv *Server, codec rp
codec = rpcClient(t, srv)
testrpc.WaitForTestAgent(t, srv.RPC, "dc1", testrpc.WithToken("root"))
// Create a new token
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
service "foo" {
policy = "write"
}
node "" {
node_prefix "" {
policy = "read"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &token); err != nil {
t.Fatalf("err: %v", err)
}
`
token = createToken(t, codec, rules)
// Register a service
regArg := structs.RegisterRequest{
@ -2896,25 +2865,12 @@ func TestCatalog_NodeServices_ACLDeny(t *testing.T) {
t.Fatalf("should not nil")
}
// Create an ACL that can read the node.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: fmt.Sprintf(`
rules := fmt.Sprintf(`
node "%s" {
policy = "read"
}
`, s1.config.NodeName),
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
`, s1.config.NodeName)
id := createToken(t, codec, rules)
// Now try with the token and it will go through.
args.Token = id

View File

@ -163,26 +163,13 @@ func TestConfigEntry_Apply_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1)
defer codec.Close()
// Create the ACL.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
service "foo" {
policy = "write"
}
operator = "write"
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
`
id := createToken(t, codec, rules)
// This should fail since we don't have write perms for the "db" service.
args := structs.ConfigEntryRequest{
@ -292,26 +279,13 @@ func TestConfigEntry_Get_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1)
defer codec.Close()
// Create the ACL.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
service "foo" {
policy = "read"
}
operator = "read"
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
`
id := createToken(t, codec, rules)
// Create some dummy service/proxy configs to be looked up.
state := s1.fsm.State()
@ -505,26 +479,13 @@ func TestConfigEntry_List_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1)
defer codec.Close()
// Create the ACL.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
service "foo" {
policy = "read"
}
operator = "read"
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
`
id := createToken(t, codec, rules)
// Create some dummy service/proxy configs to be looked up.
state := s1.fsm.State()
@ -590,26 +551,13 @@ func TestConfigEntry_ListAll_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1)
defer codec.Close()
// Create the ACL.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
service "foo" {
policy = "read"
}
operator = "read"
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
`
id := createToken(t, codec, rules)
// Create some dummy service/proxy configs to be looked up.
state := s1.fsm.State()
@ -749,26 +697,13 @@ func TestConfigEntry_Delete_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1)
defer codec.Close()
// Create the ACL.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
service "foo" {
policy = "write"
}
operator = "write"
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
`
id := createToken(t, codec, rules)
// Create some dummy service/proxy configs to be looked up.
state := s1.fsm.State()
@ -1971,26 +1906,13 @@ func TestConfigEntry_ResolveServiceConfig_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1)
defer codec.Close()
// Create the ACL.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
service "foo" {
policy = "write"
}
operator = "write"
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
`
id := createToken(t, codec, rules)
// Create some dummy service/proxy configs to be looked up.
state := s1.fsm.State()

View File

@ -1118,25 +1118,7 @@ func TestConnectCASignValidation(t *testing.T) {
testrpc.WaitForLeader(t, s1.RPC, "dc1")
// Create an ACL token with service:write for web*
var webToken string
{
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
service "web" {
policy = "write"
}`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
require.NoError(t, msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &webToken))
}
webToken := createToken(t, codec, `service "web" { policy = "write" }`)
testWebID := connect.TestSpiffeIDService(t, "web")
tests := []struct {

View File

@ -220,25 +220,7 @@ func TestCoordinate_Update_ACLDeny(t *testing.T) {
t.Fatalf("err: %v", err)
}
// Create an ACL that can write to the node.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
node "node1" {
policy = "write"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
id := createToken(t, codec, `node "node1" { policy = "write" }`)
// With the token, it should now go through.
req.Token = id
@ -460,27 +442,7 @@ func TestCoordinate_ListNodes_ACLFilter(t *testing.T) {
t.Fatalf("bad: %#v", resp.Coordinates)
}
// Create an ACL that can read one of the nodes.
var id string
{
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
node "foo" {
policy = "read"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &id); err != nil {
t.Fatalf("err: %v", err)
}
}
id := createToken(t, codec, ` node "foo" { policy = "read" } `)
// With the token, it should now go through.
arg.Token = id
@ -598,25 +560,7 @@ func TestCoordinate_Node_ACLDeny(t *testing.T) {
t.Fatalf("err: %v", err)
}
// Create an ACL that can read from the node.
aclReq := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
node "node1" {
policy = "read"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var id string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &aclReq, &id); err != nil {
t.Fatalf("err: %v", err)
}
id := createToken(t, codec, `node "node1" { policy = "read" } `)
// With the token, it should now go through.
arg.Token = id

View File

@ -260,30 +260,16 @@ func (c *FSM) applyACLOperation(buf []byte, index uint64) interface{} {
return err
}
return enabled
case structs.ACLBootstrapNow:
// This is a bootstrap request from a non-upgraded node
if err := c.state.ACLBootstrap(index, 0, req.ACL.Convert(), true); err != nil {
return err
}
// No need to check expiration times as those did not exist in legacy tokens.
if _, token, err := c.state.ACLTokenGetBySecret(nil, req.ACL.ID, nil); err != nil {
return err
} else {
acl, err := token.Convert()
if err != nil {
return err
}
return acl
}
case structs.ACLForceSet, structs.ACLSet:
case structs.ACLSet:
if err := c.state.ACLTokenSet(index, req.ACL.Convert(), true); err != nil {
return err
}
return req.ACL.ID
case structs.ACLDelete:
return c.state.ACLTokenDeleteBySecret(index, req.ACL.ID, nil)
// Legacy commands that have been removed
case "bootstrap-now", "force-set":
return fmt.Errorf("command %v has been removed with the legacy ACL system", req.Op)
default:
c.logger.Warn("Invalid ACL operation", "operation", req.Op)
return fmt.Errorf("Invalid ACL operation '%s'", req.Op)

View File

@ -923,29 +923,6 @@ func TestFSM_ACL_CRUD(t *testing.T) {
if !canBootstrap {
t.Fatalf("bad: shouldn't be able to bootstrap")
}
// Do a bootstrap.
bootstrap := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLBootstrapNow,
ACL: structs.ACL{
ID: generateUUID(),
Name: "Bootstrap Token",
Type: structs.ACLTokenTypeManagement,
},
}
buf, err = structs.Encode(structs.ACLRequestType, bootstrap)
if err != nil {
t.Fatalf("err: %v", err)
}
resp = fsm.Apply(makeLog(buf))
respACL, ok := resp.(*structs.ACL)
if !ok {
t.Fatalf("resp: %v", resp)
}
bootstrap.ACL.CreateIndex = respACL.CreateIndex
bootstrap.ACL.ModifyIndex = respACL.ModifyIndex
require.Equal(t, &bootstrap.ACL, respACL)
}
func TestFSM_PreparedQuery_CRUD(t *testing.T) {

View File

@ -993,26 +993,18 @@ func TestHealth_ServiceNodes_ConnectProxy_ACL(t *testing.T) {
testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create the ACL.
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
service "foo" {
policy = "write"
}
service "foo-proxy" {
policy = "write"
}
node "foo" {
policy = "write"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var token string
assert.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", arg, &token))
`
token := createToken(t, codec, rules)
{
var out struct{}

View File

@ -877,27 +877,12 @@ func TestIntentionApply_aclDeny(t *testing.T) {
waitForLeaderEstablishment(t, s1)
// Create an ACL with write permissions
var token string
{
var rules = `
service "foo" {
rules := `
service "foobar" {
policy = "deny"
intentions = "write"
}`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
require.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
}
token := createToken(t, codec, rules)
// Setup a basic record to create
ixn := structs.IntentionRequest{
@ -1282,27 +1267,12 @@ func TestIntentionApply_aclDelete(t *testing.T) {
waitForLeaderEstablishment(t, s1)
// Create an ACL with write permissions
var token string
{
var rules = `
service "foo" {
rules := `
service "foobar" {
policy = "deny"
intentions = "write"
}`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
require.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
}
token := createToken(t, codec, rules)
// Setup a basic record to create
ixn := structs.IntentionRequest{
@ -1363,27 +1333,12 @@ func TestIntentionApply_aclUpdate(t *testing.T) {
waitForLeaderEstablishment(t, s1)
// Create an ACL with write permissions
var token string
{
var rules = `
service "foo" {
rules := `
service "foobar" {
policy = "deny"
intentions = "write"
}`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
require.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
}
token := createToken(t, codec, rules)
// Setup a basic record to create
ixn := structs.IntentionRequest{
@ -1477,27 +1432,12 @@ func TestIntentionApply_aclUpdateChange(t *testing.T) {
waitForLeaderEstablishment(t, s1)
// Create an ACL with write permissions
var token string
{
var rules = `
service "foo" {
rules := `
service "foobar" {
policy = "deny"
intentions = "write"
}`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
require.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
}
token := createToken(t, codec, rules)
// Setup a basic record to create
ixn := structs.IntentionRequest{
@ -2018,26 +1958,11 @@ func TestIntentionCheck_aclDeny(t *testing.T) {
waitForLeaderEstablishment(t, s1)
// Create an ACL with service read permissions. This will grant permission.
var token string
{
var rules = `
rules := `
service "bar" {
policy = "read"
}`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
require.NoError(t, msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
}
token := createToken(t, codec, rules)
// Check
req := &structs.IntentionQueryRequest{

View File

@ -94,22 +94,7 @@ func TestKVS_Apply_ACLDeny(t *testing.T) {
testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create the ACL
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: testListRules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var out string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
t.Fatalf("err: %v", err)
}
id := out
id := createToken(t, codec, testListRules)
// Try a write
argR := structs.KVSRequest{
@ -459,21 +444,7 @@ func TestKVSEndpoint_List_ACLDeny(t *testing.T) {
}
}
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: testListRules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var out string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
t.Fatalf("err: %v", err)
}
id := out
id := createToken(t, codec, testListRules)
getR := structs.KeyRequest{
Datacenter: "dc1",
@ -551,32 +522,18 @@ func TestKVSEndpoint_List_ACLEnableKeyListPolicy(t *testing.T) {
//write acl policy that denies recursive reads on ""
var testListRules1 = `
key "" {
key_prefix "" {
policy = "deny"
}
key "bar" {
key_prefix "bar" {
policy = "list"
}
key "zip" {
key_prefix "zip" {
policy = "read"
}
`
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: testListRules1,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var out string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
t.Fatalf("err: %v", err)
}
id := out
id := createToken(t, codec, testListRules1)
//recursive read on empty prefix should fail
getReq := structs.KeyRequest{
@ -752,21 +709,7 @@ func TestKVSEndpoint_ListKeys_ACLDeny(t *testing.T) {
}
}
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: testListRules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var out string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &out); err != nil {
t.Fatalf("err: %v", err)
}
id := out
id := createToken(t, codec, testListRules)
getR := structs.KeyListRequest{
Datacenter: "dc1",

View File

@ -75,27 +75,7 @@ func TestOperator_Autopilot_GetConfiguration_ACLDeny(t *testing.T) {
t.Fatalf("err: %v", err)
}
// Create an ACL with operator read permissions.
var token string
{
var rules = `
operator = "read"
`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil {
t.Fatalf("err: %v", err)
}
}
token := createToken(t, codec, `operator = "read"`)
// Now we can read and verify the config
arg.Token = token
@ -182,27 +162,7 @@ func TestOperator_Autopilot_SetConfiguration_ACLDeny(t *testing.T) {
t.Fatalf("err: %v", err)
}
// Create an ACL with operator write permissions.
var token string
{
var rules = `
operator = "write"
`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil {
t.Fatalf("err: %v", err)
}
}
token := createToken(t, codec, `operator = "write"`)
// Now we can update the config
arg.Token = token

View File

@ -93,26 +93,8 @@ func TestOperator_RaftGetConfiguration_ACLDeny(t *testing.T) {
}
// Create an ACL with operator read permissions.
var token string
{
var rules = `
operator = "read"
`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil {
t.Fatalf("err: %v", err)
}
}
rules := `operator = "read"`
token := createToken(t, codec, rules)
// Now it should go through.
arg.Token = token
@ -241,27 +223,7 @@ func TestOperator_RaftRemovePeerByAddress_ACLDeny(t *testing.T) {
t.Fatalf("err: %v", err)
}
// Create an ACL with operator write permissions.
var token string
{
var rules = `
operator = "write"
`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil {
t.Fatalf("err: %v", err)
}
}
token := createToken(t, codec, `operator = "write" `)
// Now it should kick back for being an invalid config, which means it
// tried to do the operation.
@ -371,27 +333,7 @@ func TestOperator_RaftRemovePeerByID_ACLDeny(t *testing.T) {
t.Fatalf("err: %v", err)
}
// Create an ACL with operator write permissions.
var token string
{
var rules = `
operator = "write"
`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil {
t.Fatalf("err: %v", err)
}
}
token := createToken(t, codec, `operator = "write"`)
// Now it should kick back for being an invalid config, which means it
// tried to do the operation.

View File

@ -210,29 +210,12 @@ func TestPreparedQuery_Apply_ACLDeny(t *testing.T) {
testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create an ACL with write permissions for redis queries.
var token string
{
var rules = `
query "redis" {
policy = "write"
}
`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
rules := `
query_prefix "redis" {
policy = "write"
}
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil {
t.Fatalf("err: %v", err)
}
}
`
token := createToken(t, codec, rules)
// Set up a bare bones query.
query := structs.PreparedQueryRequest{
@ -656,29 +639,12 @@ func TestPreparedQuery_ACLDeny_Catchall_Template(t *testing.T) {
testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create an ACL with write permissions for any prefix.
var token string
{
var rules = `
query "" {
policy = "write"
}
`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
rules := `
query "" {
policy = "write"
}
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil {
t.Fatalf("err: %v", err)
}
}
`
token := createToken(t, codec, rules)
// Set up a catch-all template.
query := structs.PreparedQueryRequest{
@ -875,29 +841,12 @@ func TestPreparedQuery_Get(t *testing.T) {
testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create an ACL with write permissions for redis queries.
var token string
{
var rules = `
query "redis" {
policy = "write"
}
`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
rules := `
query_prefix "redis" {
policy = "write"
}
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil {
t.Fatalf("err: %v", err)
}
}
`
token := createToken(t, codec, rules)
// Set up a bare bones query.
query := structs.PreparedQueryRequest{
@ -1133,29 +1082,12 @@ func TestPreparedQuery_List(t *testing.T) {
testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create an ACL with write permissions for redis queries.
var token string
{
var rules = `
query "redis" {
policy = "write"
}
`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
rules := `
query_prefix "redis" {
policy = "write"
}
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil {
t.Fatalf("err: %v", err)
}
}
`
token := createToken(t, codec, rules)
// Query with a legit token but no queries.
{
@ -1346,29 +1278,12 @@ func TestPreparedQuery_Explain(t *testing.T) {
testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create an ACL with write permissions for prod- queries.
var token string
{
var rules = `
query "prod-" {
policy = "write"
}
`
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: rules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
rules := `
query_prefix "prod-" {
policy = "write"
}
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil {
t.Fatalf("err: %v", err)
}
}
`
token := createToken(t, codec, rules)
// Set up a template.
query := structs.PreparedQueryRequest{
@ -1515,52 +1430,13 @@ func TestPreparedQuery_Execute(t *testing.T) {
testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
testrpc.WaitForLeader(t, s1.RPC, "dc2", testrpc.WithToken("root"))
// Create ACL tokens with read permission to the service and to the service
// and all nodes.
var execNoNodesToken string
{
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `service "foo" { policy = "read" }`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
require.NoError(t, msgpackrpc.CallWithCodec(codec1, "ACL.Apply", &req, &execNoNodesToken))
}
var execToken string
{
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `service "foo" { policy = "read" }
node "" { policy = "read" }`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
require.NoError(t, msgpackrpc.CallWithCodec(codec1, "ACL.Apply", &req, &execToken))
}
// Make a new exec token that can't read the service.
var denyToken string
{
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `service "foo" { policy = "deny" }`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
require.NoError(t, msgpackrpc.CallWithCodec(codec1, "ACL.Apply", &req, &denyToken))
}
execNoNodesToken := createTokenWithPolicyName(t, "no-nodes", codec1, `service_prefix "foo" { policy = "read" }`)
rules := `
service_prefix "foo" { policy = "read" }
node_prefix "" { policy = "read" }
`
execToken := createTokenWithPolicyName(t, "with-read", codec1, rules)
denyToken := createTokenWithPolicyName(t, "with-deny", codec1, `service_prefix "foo" { policy = "deny" }`)
newSessionDC1 := func(t *testing.T) string {
t.Helper()

View File

@ -167,26 +167,12 @@ func TestSession_Apply_ACLDeny(t *testing.T) {
testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create the ACL.
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
session "foo" {
policy = "write"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var token string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil {
t.Fatalf("err: %v", err)
}
`
token := createToken(t, codec, rules)
// Just add a node.
s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"})
@ -405,26 +391,12 @@ func TestSession_Get_List_NodeSessions_ACLFilter(t *testing.T) {
testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create the ACL.
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
session "foo" {
policy = "read"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var token string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil {
t.Fatalf("err: %v", err)
}
`
token := createToken(t, codec, rules)
// Create a node and a session.
s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"})
@ -764,26 +736,12 @@ func TestSession_Renew_ACLDeny(t *testing.T) {
testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create the ACL.
req := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: `
rules := `
session "foo" {
policy = "write"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var token string
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil {
t.Fatalf("err: %v", err)
}
`
token := createToken(t, codec, rules)
// Just add a node.
s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"})

View File

@ -348,23 +348,7 @@ func TestTxn_Apply_ACLDeny(t *testing.T) {
check := structs.HealthCheck{Node: "nope", CheckID: types.CheckID("nope")}
state.EnsureCheck(4, &check)
// Create the ACL.
var id string
{
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: testTxnRules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
if err := s1.RPC("ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
}
id := createToken(t, rpcClient(t, s1), testTxnRules)
// Set up a transaction where every operation should get blocked due to
// ACLs.
@ -888,23 +872,7 @@ func TestTxn_Read_ACLDeny(t *testing.T) {
check := structs.HealthCheck{Node: "nope", CheckID: types.CheckID("nope")}
state.EnsureCheck(4, &check)
// Create the ACL.
var id string
{
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: testTxnRules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err)
}
}
id := createToken(t, codec, testTxnRules)
// Set up a transaction where every operation should get blocked due to
// ACLs.

View File

@ -9,11 +9,9 @@ import (
"testing"
"time"
"github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/sdk/testutil/retry"
"github.com/hashicorp/consul/testrpc"
)
func TestEventFire(t *testing.T) {
@ -72,21 +70,7 @@ func TestEventFire_token(t *testing.T) {
defer a.Shutdown()
testrpc.WaitForLeader(t, a.RPC, "dc1")
// Create an ACL token
args := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: testEventPolicy,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var token string
if err := a.RPC("ACL.Apply", &args, &token); err != nil {
t.Fatalf("err: %v", err)
}
token := createToken(t, a, testEventPolicy)
type tcase struct {
event string

View File

@ -8,6 +8,7 @@ import (
"time"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -791,23 +792,7 @@ func TestAgentAntiEntropy_Services_ACLDeny(t *testing.T) {
defer a.Shutdown()
testrpc.WaitForLeader(t, a.RPC, "dc1")
// Create the ACL
arg := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: testRegisterRules,
},
WriteRequest: structs.WriteRequest{
Token: "root",
},
}
var token string
if err := a.RPC("ACL.Apply", &arg, &token); err != nil {
t.Fatalf("err: %v", err)
}
token := createToken(t, a, testRegisterRules)
// Create service (disallowed)
srv1 := &structs.NodeService{
@ -929,6 +914,40 @@ func TestAgentAntiEntropy_Services_ACLDeny(t *testing.T) {
}
}
type RPC interface {
RPC(method string, args interface{}, reply interface{}) error
}
func createToken(t *testing.T, rpc RPC, policyRules string) string {
t.Helper()
reqPolicy := structs.ACLPolicySetRequest{
Datacenter: "dc1",
Policy: structs.ACLPolicy{
Name: "the-policy",
Rules: policyRules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
err := rpc.RPC("ACL.PolicySet", &reqPolicy, &structs.ACLPolicy{})
require.NoError(t, err)
token, err := uuid.GenerateUUID()
require.NoError(t, err)
reqToken := structs.ACLTokenSetRequest{
Datacenter: "dc1",
ACLToken: structs.ACLToken{
SecretID: token,
Policies: []structs.ACLTokenPolicyLink{{Name: "the-policy"}},
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
err = rpc.RPC("ACL.TokenSet", &reqToken, &structs.ACLToken{})
require.NoError(t, err)
return token
}
func TestAgentAntiEntropy_Checks(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
@ -1222,23 +1241,7 @@ func TestAgentAntiEntropy_Checks_ACLDeny(t *testing.T) {
testrpc.WaitForLeader(t, a.RPC, dc)
// Create the ACL
arg := structs.ACLRequest{
Datacenter: dc,
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: testRegisterRules,
},
WriteRequest: structs.WriteRequest{
Token: "root",
},
}
var token string
if err := a.RPC("ACL.Apply", &arg, &token); err != nil {
t.Fatalf("err: %v", err)
}
token := createToken(t, a, testRegisterRules)
// Create services using the root token
srv1 := &structs.NodeService{

View File

@ -42,13 +42,6 @@ const (
ACLTokenAccessor ACLTokenIDType = "accessor"
)
type ACLPolicyIDType string
const (
ACLPolicyName ACLPolicyIDType = "name"
ACLPolicyID ACLPolicyIDType = "id"
)
const (
// All policy ids with the first 120 bits set to all zeroes are
// reserved for builtin policies. Policy creation will ensure we
@ -98,9 +91,11 @@ func ACLIDReserved(id string) bool {
const (
// ACLSet creates or updates a token.
// TODO(ACL-Legacy-Compat): remove
ACLSet ACLOp = "set"
// ACLDelete deletes a token.
// TODO(ACL-Legacy-Compat): remove
ACLDelete ACLOp = "delete"
)

View File

@ -7,7 +7,6 @@
package structs
import (
"errors"
"fmt"
"time"
@ -18,21 +17,10 @@ const (
// ACLBootstrapInit is used to perform a scan for existing tokens which
// will decide whether bootstrapping is allowed for a cluster. This is
// initiated by the leader when it steps up, if necessary.
// TODO(ACL-Legacy-Compat): remove
ACLBootstrapInit ACLOp = "bootstrap-init"
// ACLBootstrapNow is used to perform a one-time ACL bootstrap operation on
// a cluster to get the first management token.
ACLBootstrapNow ACLOp = "bootstrap-now"
// ACLForceSet is deprecated, but left for backwards compatibility.
ACLForceSet ACLOp = "force-set"
)
// ACLBootstrapNotInitializedErr is returned when a bootstrap is attempted but
// we haven't yet initialized ACL bootstrap. It provides some guidance to
// operators on how to proceed.
var ACLBootstrapNotInitializedErr = errors.New("ACL bootstrap not initialized, need to force a leader election and ensure all Consul servers support this feature")
const (
// ACLTokenTypeClient tokens have rules applied
ACLTokenTypeClient = "client"
@ -62,6 +50,7 @@ type ACLs []*ACL
// equivalent. This will NOT fill in the other ACLToken fields or perform any other
// upgrade (other than correcting an older HCL syntax that is no longer
// supported).
// TODO(ACL-Legacy-Compat): remove
func (a *ACL) Convert() *ACLToken {
// Ensure that we correct any old HCL in legacy tokens to prevent old
// syntax from leaking elsewhere into the system.

View File

@ -4,6 +4,9 @@ import (
"strings"
"testing"
"github.com/hashicorp/go-uuid"
"github.com/stretchr/testify/require"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/sdk/testutil/retry"
@ -205,21 +208,7 @@ func TestUserEventToken(t *testing.T) {
`)
defer a.Shutdown()
// Create an ACL token
args := structs.ACLRequest{
Datacenter: "dc1",
Op: structs.ACLSet,
ACL: structs.ACL{
Name: "User token",
Type: structs.ACLTokenTypeClient,
Rules: testEventPolicy,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
var token string
if err := a.RPC("ACL.Apply", &args, &token); err != nil {
t.Fatalf("err: %v", err)
}
token := createToken(t, a, testEventPolicy)
type tcase struct {
name string
@ -241,6 +230,40 @@ func TestUserEventToken(t *testing.T) {
}
}
type RPC interface {
RPC(method string, args interface{}, reply interface{}) error
}
func createToken(t *testing.T, rpc RPC, policyRules string) string {
t.Helper()
reqPolicy := structs.ACLPolicySetRequest{
Datacenter: "dc1",
Policy: structs.ACLPolicy{
Name: "the-policy",
Rules: policyRules,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
err := rpc.RPC("ACL.PolicySet", &reqPolicy, &structs.ACLPolicy{})
require.NoError(t, err)
token, err := uuid.GenerateUUID()
require.NoError(t, err)
reqToken := structs.ACLTokenSetRequest{
Datacenter: "dc1",
ACLToken: structs.ACLToken{
SecretID: token,
Policies: []structs.ACLTokenPolicyLink{{Name: "the-policy"}},
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
err = rpc.RPC("ACL.TokenSet", &reqToken, &structs.ACLToken{})
require.NoError(t, err)
return token
}
const testEventPolicy = `
event "foo" {
policy = "deny"