Merge pull request #10986 from hashicorp/dnephin/acl-legacy-remove-rpc
acl: remove legacy ACL RPC - part 1
This commit is contained in:
commit
acb62aa896
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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{}
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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"})
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue