mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 10:25:42 +03:00
nomad: ACL endpoints check support enabled and redirect to authority
This commit is contained in:
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
func TestHTTP_ACLPolicyList(t *testing.T) {
|
||||
t.Parallel()
|
||||
httpTest(t, nil, func(s *TestAgent) {
|
||||
httpACLTest(t, nil, func(s *TestAgent) {
|
||||
p1 := mock.ACLPolicy()
|
||||
p2 := mock.ACLPolicy()
|
||||
p3 := mock.ACLPolicy()
|
||||
@@ -59,7 +59,7 @@ func TestHTTP_ACLPolicyList(t *testing.T) {
|
||||
|
||||
func TestHTTP_ACLPolicyQuery(t *testing.T) {
|
||||
t.Parallel()
|
||||
httpTest(t, nil, func(s *TestAgent) {
|
||||
httpACLTest(t, nil, func(s *TestAgent) {
|
||||
p1 := mock.ACLPolicy()
|
||||
args := structs.ACLPolicyUpsertRequest{
|
||||
Policies: []*structs.ACLPolicy{p1},
|
||||
@@ -104,7 +104,7 @@ func TestHTTP_ACLPolicyQuery(t *testing.T) {
|
||||
|
||||
func TestHTTP_ACLPolicyCreate(t *testing.T) {
|
||||
t.Parallel()
|
||||
httpTest(t, nil, func(s *TestAgent) {
|
||||
httpACLTest(t, nil, func(s *TestAgent) {
|
||||
// Make the HTTP request
|
||||
p1 := mock.ACLPolicy()
|
||||
buf := encodeReq(p1)
|
||||
@@ -138,7 +138,7 @@ func TestHTTP_ACLPolicyCreate(t *testing.T) {
|
||||
|
||||
func TestHTTP_ACLPolicyDelete(t *testing.T) {
|
||||
t.Parallel()
|
||||
httpTest(t, nil, func(s *TestAgent) {
|
||||
httpACLTest(t, nil, func(s *TestAgent) {
|
||||
p1 := mock.ACLPolicy()
|
||||
args := structs.ACLPolicyUpsertRequest{
|
||||
Policies: []*structs.ACLPolicy{p1},
|
||||
@@ -176,7 +176,11 @@ func TestHTTP_ACLPolicyDelete(t *testing.T) {
|
||||
|
||||
func TestHTTP_ACLTokenBootstrap(t *testing.T) {
|
||||
t.Parallel()
|
||||
httpTest(t, nil, func(s *TestAgent) {
|
||||
conf := func(c *Config) {
|
||||
c.ACL.Enabled = true
|
||||
c.ACL.PolicyTTL = 0 // Special flag to disable auto-bootstrap
|
||||
}
|
||||
httpTest(t, conf, func(s *TestAgent) {
|
||||
// Make the HTTP request
|
||||
req, err := http.NewRequest("PUT", "/v1/acl/bootstrap", nil)
|
||||
if err != nil {
|
||||
@@ -204,7 +208,7 @@ func TestHTTP_ACLTokenBootstrap(t *testing.T) {
|
||||
|
||||
func TestHTTP_ACLTokenList(t *testing.T) {
|
||||
t.Parallel()
|
||||
httpTest(t, nil, func(s *TestAgent) {
|
||||
httpACLTest(t, nil, func(s *TestAgent) {
|
||||
p1 := mock.ACLToken()
|
||||
p1.AccessorID = ""
|
||||
p2 := mock.ACLToken()
|
||||
@@ -244,9 +248,9 @@ func TestHTTP_ACLTokenList(t *testing.T) {
|
||||
t.Fatalf("missing last contact")
|
||||
}
|
||||
|
||||
// Check the output
|
||||
// Check the output (includes boostrap token)
|
||||
n := obj.([]*structs.ACLTokenListStub)
|
||||
if len(n) != 3 {
|
||||
if len(n) != 4 {
|
||||
t.Fatalf("bad: %#v", n)
|
||||
}
|
||||
})
|
||||
@@ -254,7 +258,7 @@ func TestHTTP_ACLTokenList(t *testing.T) {
|
||||
|
||||
func TestHTTP_ACLTokenQuery(t *testing.T) {
|
||||
t.Parallel()
|
||||
httpTest(t, nil, func(s *TestAgent) {
|
||||
httpACLTest(t, nil, func(s *TestAgent) {
|
||||
p1 := mock.ACLToken()
|
||||
p1.AccessorID = ""
|
||||
args := structs.ACLTokenUpsertRequest{
|
||||
@@ -299,7 +303,7 @@ func TestHTTP_ACLTokenQuery(t *testing.T) {
|
||||
|
||||
func TestHTTP_ACLTokenCreate(t *testing.T) {
|
||||
t.Parallel()
|
||||
httpTest(t, nil, func(s *TestAgent) {
|
||||
httpACLTest(t, nil, func(s *TestAgent) {
|
||||
// Make the HTTP request
|
||||
p1 := mock.ACLToken()
|
||||
p1.AccessorID = ""
|
||||
@@ -332,7 +336,7 @@ func TestHTTP_ACLTokenCreate(t *testing.T) {
|
||||
|
||||
func TestHTTP_ACLTokenDelete(t *testing.T) {
|
||||
t.Parallel()
|
||||
httpTest(t, nil, func(s *TestAgent) {
|
||||
httpACLTest(t, nil, func(s *TestAgent) {
|
||||
p1 := mock.ACLToken()
|
||||
p1.AccessorID = ""
|
||||
args := structs.ACLTokenUpsertRequest{
|
||||
|
||||
@@ -496,6 +496,18 @@ func httpTest(t testing.TB, cb func(c *Config), f func(srv *TestAgent)) {
|
||||
f(s)
|
||||
}
|
||||
|
||||
func httpACLTest(t testing.TB, cb func(c *Config), f func(srv *TestAgent)) {
|
||||
s := makeHTTPServer(t, func(c *Config) {
|
||||
c.ACL.Enabled = true
|
||||
if cb != nil {
|
||||
cb(c)
|
||||
}
|
||||
})
|
||||
defer s.Shutdown()
|
||||
testutil.WaitForLeader(t, s.Agent.RPC)
|
||||
f(s)
|
||||
}
|
||||
|
||||
func encodeReq(obj interface{}) io.ReadCloser {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
enc := json.NewEncoder(buf)
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/hashicorp/nomad/api"
|
||||
"github.com/hashicorp/nomad/client/fingerprint"
|
||||
"github.com/hashicorp/nomad/nomad"
|
||||
"github.com/hashicorp/nomad/nomad/mock"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
sconfig "github.com/hashicorp/nomad/nomad/structs/config"
|
||||
"github.com/hashicorp/nomad/testutil"
|
||||
@@ -66,6 +67,9 @@ type TestAgent struct {
|
||||
// Agent is the embedded Nomad agent.
|
||||
// It is valid after Start().
|
||||
*Agent
|
||||
|
||||
// Token is auto-bootstrapped if ACLs are enabled
|
||||
Token *structs.ACLToken
|
||||
}
|
||||
|
||||
// NewTestAgent returns a started agent with the given name and
|
||||
@@ -164,6 +168,17 @@ func (a *TestAgent) Start() *TestAgent {
|
||||
panic(fmt.Sprintf("failed OK response: %v", err))
|
||||
})
|
||||
}
|
||||
|
||||
// Check if ACLs enabled. Use special value of PolicyTTL 0s
|
||||
// to do a bypass of this step. This is so we can test bootstrap
|
||||
// without having to pass down a special flag.
|
||||
if a.Config.ACL.Enabled && a.Config.Server.Enabled && a.Config.ACL.PolicyTTL != 0 {
|
||||
a.Token = mock.ACLManagementToken()
|
||||
state := a.Agent.server.State()
|
||||
if err := state.BootstrapACLTokens(1, a.Token); err != nil {
|
||||
panic(fmt.Sprintf("token bootstrap failed: %v", err))
|
||||
}
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,11 @@ import (
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
|
||||
var (
|
||||
// aclDisabled is returned when an ACL endpoint is hit but ACLs are not enabled
|
||||
aclDisabled = fmt.Errorf("ACL support disabled")
|
||||
)
|
||||
|
||||
// ACL endpoint is used for manipulating ACL tokens and policies
|
||||
type ACL struct {
|
||||
srv *Server
|
||||
@@ -17,6 +22,12 @@ type ACL struct {
|
||||
|
||||
// UpsertPolicies is used to create or update a set of policies
|
||||
func (a *ACL) UpsertPolicies(args *structs.ACLPolicyUpsertRequest, reply *structs.GenericResponse) error {
|
||||
// Ensure ACLs are enabled, and always flow modification requests to the authoritative region
|
||||
if !a.srv.config.ACLEnabled {
|
||||
return aclDisabled
|
||||
}
|
||||
args.Region = a.srv.config.AuthoritativeRegion
|
||||
|
||||
if done, err := a.srv.forward("ACL.UpsertPolicies", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
@@ -47,6 +58,12 @@ func (a *ACL) UpsertPolicies(args *structs.ACLPolicyUpsertRequest, reply *struct
|
||||
|
||||
// DeletePolicies is used to delete policies
|
||||
func (a *ACL) DeletePolicies(args *structs.ACLPolicyDeleteRequest, reply *structs.GenericResponse) error {
|
||||
// Ensure ACLs are enabled, and always flow modification requests to the authoritative region
|
||||
if !a.srv.config.ACLEnabled {
|
||||
return aclDisabled
|
||||
}
|
||||
args.Region = a.srv.config.AuthoritativeRegion
|
||||
|
||||
if done, err := a.srv.forward("ACL.DeletePolicies", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
@@ -70,6 +87,9 @@ func (a *ACL) DeletePolicies(args *structs.ACLPolicyDeleteRequest, reply *struct
|
||||
|
||||
// ListPolicies is used to list the policies
|
||||
func (a *ACL) ListPolicies(args *structs.ACLPolicyListRequest, reply *structs.ACLPolicyListResponse) error {
|
||||
if !a.srv.config.ACLEnabled {
|
||||
return aclDisabled
|
||||
}
|
||||
if done, err := a.srv.forward("ACL.ListPolicies", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
@@ -122,6 +142,9 @@ func (a *ACL) ListPolicies(args *structs.ACLPolicyListRequest, reply *structs.AC
|
||||
|
||||
// GetPolicy is used to get a specific policy
|
||||
func (a *ACL) GetPolicy(args *structs.ACLPolicySpecificRequest, reply *structs.SingleACLPolicyResponse) error {
|
||||
if !a.srv.config.ACLEnabled {
|
||||
return aclDisabled
|
||||
}
|
||||
if done, err := a.srv.forward("ACL.GetPolicy", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
@@ -157,6 +180,9 @@ func (a *ACL) GetPolicy(args *structs.ACLPolicySpecificRequest, reply *structs.S
|
||||
|
||||
// GetPolicies is used to get a set of policies
|
||||
func (a *ACL) GetPolicies(args *structs.ACLPolicySetRequest, reply *structs.ACLPolicySetResponse) error {
|
||||
if !a.srv.config.ACLEnabled {
|
||||
return aclDisabled
|
||||
}
|
||||
if done, err := a.srv.forward("ACL.GetPolicies", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
@@ -194,6 +220,12 @@ func (a *ACL) GetPolicies(args *structs.ACLPolicySetRequest, reply *structs.ACLP
|
||||
|
||||
// Bootstrap is used to bootstrap the initial token
|
||||
func (a *ACL) Bootstrap(args *structs.ACLTokenBootstrapRequest, reply *structs.ACLTokenUpsertResponse) error {
|
||||
// Ensure ACLs are enabled, and always flow modification requests to the authoritative region
|
||||
if !a.srv.config.ACLEnabled {
|
||||
return aclDisabled
|
||||
}
|
||||
args.Region = a.srv.config.AuthoritativeRegion
|
||||
|
||||
if done, err := a.srv.forward("ACL.Bootstrap", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
@@ -250,6 +282,12 @@ func (a *ACL) Bootstrap(args *structs.ACLTokenBootstrapRequest, reply *structs.A
|
||||
|
||||
// UpsertTokens is used to create or update a set of tokens
|
||||
func (a *ACL) UpsertTokens(args *structs.ACLTokenUpsertRequest, reply *structs.ACLTokenUpsertResponse) error {
|
||||
// Ensure ACLs are enabled, and always flow modification requests to the authoritative region
|
||||
if !a.srv.config.ACLEnabled {
|
||||
return aclDisabled
|
||||
}
|
||||
args.Region = a.srv.config.AuthoritativeRegion
|
||||
|
||||
if done, err := a.srv.forward("ACL.UpsertTokens", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
@@ -322,6 +360,12 @@ func (a *ACL) UpsertTokens(args *structs.ACLTokenUpsertRequest, reply *structs.A
|
||||
|
||||
// DeleteTokens is used to delete tokens
|
||||
func (a *ACL) DeleteTokens(args *structs.ACLTokenDeleteRequest, reply *structs.GenericResponse) error {
|
||||
// Ensure ACLs are enabled, and always flow modification requests to the authoritative region
|
||||
if !a.srv.config.ACLEnabled {
|
||||
return aclDisabled
|
||||
}
|
||||
args.Region = a.srv.config.AuthoritativeRegion
|
||||
|
||||
if done, err := a.srv.forward("ACL.DeleteTokens", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
@@ -345,6 +389,9 @@ func (a *ACL) DeleteTokens(args *structs.ACLTokenDeleteRequest, reply *structs.G
|
||||
|
||||
// ListTokens is used to list the tokens
|
||||
func (a *ACL) ListTokens(args *structs.ACLTokenListRequest, reply *structs.ACLTokenListResponse) error {
|
||||
if !a.srv.config.ACLEnabled {
|
||||
return aclDisabled
|
||||
}
|
||||
if done, err := a.srv.forward("ACL.ListTokens", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
@@ -393,6 +440,9 @@ func (a *ACL) ListTokens(args *structs.ACLTokenListRequest, reply *structs.ACLTo
|
||||
|
||||
// GetToken is used to get a specific token
|
||||
func (a *ACL) GetToken(args *structs.ACLTokenSpecificRequest, reply *structs.SingleACLTokenResponse) error {
|
||||
if !a.srv.config.ACLEnabled {
|
||||
return aclDisabled
|
||||
}
|
||||
if done, err := a.srv.forward("ACL.GetToken", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
@@ -428,6 +478,9 @@ func (a *ACL) GetToken(args *structs.ACLTokenSpecificRequest, reply *structs.Sin
|
||||
|
||||
// GetTokens is used to get a set of token
|
||||
func (a *ACL) GetTokens(args *structs.ACLTokenSetRequest, reply *structs.ACLTokenSetResponse) error {
|
||||
if !a.srv.config.ACLEnabled {
|
||||
return aclDisabled
|
||||
}
|
||||
if done, err := a.srv.forward("ACL.GetTokens", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
@@ -465,6 +518,9 @@ func (a *ACL) GetTokens(args *structs.ACLTokenSetRequest, reply *structs.ACLToke
|
||||
|
||||
// ResolveToken is used to lookup a specific token by a secret ID. This is used for enforcing ACLs by clients.
|
||||
func (a *ACL) ResolveToken(args *structs.ResolveACLTokenRequest, reply *structs.ResolveACLTokenResponse) error {
|
||||
if !a.srv.config.ACLEnabled {
|
||||
return aclDisabled
|
||||
}
|
||||
if done, err := a.srv.forward("ACL.ResolveToken", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
func TestACLEndpoint_GetPolicy(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
@@ -46,7 +46,7 @@ func TestACLEndpoint_GetPolicy(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_GetPolicy_Blocking(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
state := s1.fsm.State()
|
||||
codec := rpcClient(t, s1)
|
||||
@@ -124,7 +124,7 @@ func TestACLEndpoint_GetPolicy_Blocking(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_GetPolicies(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
@@ -160,7 +160,7 @@ func TestACLEndpoint_GetPolicies(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_GetPolicies_Blocking(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
state := s1.fsm.State()
|
||||
codec := rpcClient(t, s1)
|
||||
@@ -238,7 +238,7 @@ func TestACLEndpoint_GetPolicies_Blocking(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_ListPolicies(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
@@ -279,7 +279,7 @@ func TestACLEndpoint_ListPolicies(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_ListPolicies_Blocking(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
state := s1.fsm.State()
|
||||
codec := rpcClient(t, s1)
|
||||
@@ -338,7 +338,7 @@ func TestACLEndpoint_ListPolicies_Blocking(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_DeletePolicies(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
@@ -361,7 +361,7 @@ func TestACLEndpoint_DeletePolicies(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_UpsertPolicies(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
@@ -388,7 +388,7 @@ func TestACLEndpoint_UpsertPolicies(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_UpsertPolicies_Invalid(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
@@ -412,7 +412,7 @@ func TestACLEndpoint_UpsertPolicies_Invalid(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_GetToken(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
@@ -444,7 +444,7 @@ func TestACLEndpoint_GetToken(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_GetToken_Blocking(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
state := s1.fsm.State()
|
||||
codec := rpcClient(t, s1)
|
||||
@@ -522,7 +522,7 @@ func TestACLEndpoint_GetToken_Blocking(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_GetTokens(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
@@ -557,7 +557,7 @@ func TestACLEndpoint_GetTokens(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_GetTokens_Blocking(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
state := s1.fsm.State()
|
||||
codec := rpcClient(t, s1)
|
||||
@@ -635,7 +635,7 @@ func TestACLEndpoint_GetTokens_Blocking(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_ListTokens(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
@@ -658,7 +658,7 @@ func TestACLEndpoint_ListTokens(t *testing.T) {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
assert.Equal(t, uint64(1000), resp.Index)
|
||||
assert.Equal(t, 2, len(resp.Tokens))
|
||||
assert.Equal(t, 3, len(resp.Tokens))
|
||||
|
||||
// Lookup the tokens by prefix
|
||||
get = &structs.ACLTokenListRequest{
|
||||
@@ -686,12 +686,12 @@ func TestACLEndpoint_ListTokens(t *testing.T) {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
assert.Equal(t, uint64(1000), resp3.Index)
|
||||
assert.Equal(t, 1, len(resp3.Tokens))
|
||||
assert.Equal(t, 2, len(resp3.Tokens))
|
||||
}
|
||||
|
||||
func TestACLEndpoint_ListTokens_Blocking(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
state := s1.fsm.State()
|
||||
codec := rpcClient(t, s1)
|
||||
@@ -702,7 +702,7 @@ func TestACLEndpoint_ListTokens_Blocking(t *testing.T) {
|
||||
|
||||
// Upsert eval triggers watches
|
||||
time.AfterFunc(100*time.Millisecond, func() {
|
||||
if err := state.UpsertACLTokens(2, []*structs.ACLToken{token}); err != nil {
|
||||
if err := state.UpsertACLTokens(3, []*structs.ACLToken{token}); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
})
|
||||
@@ -710,7 +710,7 @@ func TestACLEndpoint_ListTokens_Blocking(t *testing.T) {
|
||||
req := &structs.ACLTokenListRequest{
|
||||
QueryOptions: structs.QueryOptions{
|
||||
Region: "global",
|
||||
MinQueryIndex: 1,
|
||||
MinQueryIndex: 2,
|
||||
},
|
||||
}
|
||||
start := time.Now()
|
||||
@@ -722,19 +722,19 @@ func TestACLEndpoint_ListTokens_Blocking(t *testing.T) {
|
||||
if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
|
||||
t.Fatalf("should block (returned in %s) %#v", elapsed, resp)
|
||||
}
|
||||
assert.Equal(t, uint64(2), resp.Index)
|
||||
if len(resp.Tokens) != 1 || resp.Tokens[0].AccessorID != token.AccessorID {
|
||||
assert.Equal(t, uint64(3), resp.Index)
|
||||
if len(resp.Tokens) != 2 {
|
||||
t.Fatalf("bad: %#v", resp.Tokens)
|
||||
}
|
||||
|
||||
// Eval deletion triggers watches
|
||||
time.AfterFunc(100*time.Millisecond, func() {
|
||||
if err := state.DeleteACLTokens(3, []string{token.AccessorID}); err != nil {
|
||||
if err := state.DeleteACLTokens(4, []string{token.AccessorID}); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
req.MinQueryIndex = 2
|
||||
req.MinQueryIndex = 3
|
||||
start = time.Now()
|
||||
var resp2 structs.ACLTokenListResponse
|
||||
if err := msgpackrpc.CallWithCodec(codec, "ACL.ListTokens", req, &resp2); err != nil {
|
||||
@@ -744,13 +744,13 @@ func TestACLEndpoint_ListTokens_Blocking(t *testing.T) {
|
||||
if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
|
||||
t.Fatalf("should block (returned in %s) %#v", elapsed, resp2)
|
||||
}
|
||||
assert.Equal(t, uint64(3), resp2.Index)
|
||||
assert.Equal(t, 0, len(resp2.Tokens))
|
||||
assert.Equal(t, uint64(4), resp2.Index)
|
||||
assert.Equal(t, 1, len(resp2.Tokens))
|
||||
}
|
||||
|
||||
func TestACLEndpoint_DeleteTokens(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
@@ -773,7 +773,9 @@ func TestACLEndpoint_DeleteTokens(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_Bootstrap(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1 := testServer(t, func(c *Config) {
|
||||
c.ACLEnabled = true
|
||||
})
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
@@ -806,7 +808,7 @@ func TestACLEndpoint_Bootstrap(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_UpsertTokens(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
@@ -859,7 +861,7 @@ func TestACLEndpoint_UpsertTokens(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_UpsertTokens_Invalid(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
@@ -883,7 +885,7 @@ func TestACLEndpoint_UpsertTokens_Invalid(t *testing.T) {
|
||||
|
||||
func TestACLEndpoint_ResolveToken(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
s1, _ := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
|
||||
@@ -371,3 +371,16 @@ func ACLToken() *structs.ACLToken {
|
||||
ModifyIndex: 20,
|
||||
}
|
||||
}
|
||||
|
||||
func ACLManagementToken() *structs.ACLToken {
|
||||
return &structs.ACLToken{
|
||||
AccessorID: structs.GenerateUUID(),
|
||||
SecretID: structs.GenerateUUID(),
|
||||
Name: "management " + structs.GenerateUUID(),
|
||||
Type: "management",
|
||||
Global: true,
|
||||
CreateTime: time.Now().UTC(),
|
||||
CreateIndex: 10,
|
||||
ModifyIndex: 20,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/nomad/command/agent/consul"
|
||||
"github.com/hashicorp/nomad/nomad/mock"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
"github.com/hashicorp/nomad/nomad/structs/config"
|
||||
"github.com/hashicorp/nomad/testutil"
|
||||
@@ -38,6 +39,21 @@ func tmpDir(t *testing.T) string {
|
||||
return dir
|
||||
}
|
||||
|
||||
func testACLServer(t *testing.T, cb func(*Config)) (*Server, *structs.ACLToken) {
|
||||
server := testServer(t, func(c *Config) {
|
||||
c.ACLEnabled = true
|
||||
if cb != nil {
|
||||
cb(c)
|
||||
}
|
||||
})
|
||||
token := mock.ACLManagementToken()
|
||||
err := server.State().BootstrapACLTokens(1, token)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to bootstrap ACL token: %v", err)
|
||||
}
|
||||
return server, token
|
||||
}
|
||||
|
||||
func testServer(t *testing.T, cb func(*Config)) *Server {
|
||||
// Setup the default settings
|
||||
config := DefaultConfig()
|
||||
|
||||
Reference in New Issue
Block a user