Update token language to distinguish Accessor and Secret ID usage (#16044)
* remove legacy tokens * remove lingering legacy token references from docs * update language and naming for token secrets and accessor IDs * updates all tokenID references to clarify accessorID * remove token type references and lookup tokens by accessorID index * remove unnecessary constants * replace additional tokenID param names * Add warning info for deprecated -id parameter Co-authored-by: Paul Glass <pglass@hashicorp.com> * Update field comment Co-authored-by: Paul Glass <pglass@hashicorp.com> --------- Co-authored-by: Paul Glass <pglass@hashicorp.com>
This commit is contained in:
parent
1777e9ec8f
commit
8e929906fa
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:deprecation
|
||||||
|
cli: The `-id` flag on acl token operations has been changed to `-accessor-id` for clarity in documentation. The `-id` flag will continue to work, but operators should use `-accessor-id` in the future.
|
||||||
|
```
|
|
@ -5,13 +5,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SyntaxVersion int
|
|
||||||
|
|
||||||
const (
|
|
||||||
SyntaxCurrent SyntaxVersion = iota
|
|
||||||
SyntaxLegacy
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PolicyDeny = "deny"
|
PolicyDeny = "deny"
|
||||||
PolicyRead = "read"
|
PolicyRead = "read"
|
||||||
|
|
|
@ -295,7 +295,7 @@ func (s *HTTPHandlers) ACLTokenCRUD(resp http.ResponseWriter, req *http.Request)
|
||||||
return nil, aclDisabled
|
return nil, aclDisabled
|
||||||
}
|
}
|
||||||
|
|
||||||
var fn func(resp http.ResponseWriter, req *http.Request, tokenID string) (interface{}, error)
|
var fn func(resp http.ResponseWriter, req *http.Request, tokenAccessorID string) (interface{}, error)
|
||||||
|
|
||||||
switch req.Method {
|
switch req.Method {
|
||||||
case "GET":
|
case "GET":
|
||||||
|
@ -311,16 +311,16 @@ func (s *HTTPHandlers) ACLTokenCRUD(resp http.ResponseWriter, req *http.Request)
|
||||||
return nil, MethodNotAllowedError{req.Method, []string{"GET", "PUT", "DELETE"}}
|
return nil, MethodNotAllowedError{req.Method, []string{"GET", "PUT", "DELETE"}}
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenID := strings.TrimPrefix(req.URL.Path, "/v1/acl/token/")
|
tokenAccessorID := strings.TrimPrefix(req.URL.Path, "/v1/acl/token/")
|
||||||
if strings.HasSuffix(tokenID, "/clone") && req.Method == "PUT" {
|
if strings.HasSuffix(tokenAccessorID, "/clone") && req.Method == "PUT" {
|
||||||
tokenID = tokenID[:len(tokenID)-6]
|
tokenAccessorID = tokenAccessorID[:len(tokenAccessorID)-6]
|
||||||
fn = s.ACLTokenClone
|
fn = s.ACLTokenClone
|
||||||
}
|
}
|
||||||
if tokenID == "" && req.Method != "PUT" {
|
if tokenAccessorID == "" && req.Method != "PUT" {
|
||||||
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Missing token ID"}
|
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Missing token AccessorID"}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fn(resp, req, tokenID)
|
return fn(resp, req, tokenAccessorID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *HTTPHandlers) ACLTokenSelf(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
func (s *HTTPHandlers) ACLTokenSelf(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
|
@ -336,7 +336,7 @@ func (s *HTTPHandlers) ACLTokenSelf(resp http.ResponseWriter, req *http.Request)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the token parameter to the ID
|
// copy the token secret parameter to the ID
|
||||||
args.TokenID = args.Token
|
args.TokenID = args.Token
|
||||||
|
|
||||||
if args.Datacenter == "" {
|
if args.Datacenter == "" {
|
||||||
|
@ -364,10 +364,10 @@ func (s *HTTPHandlers) ACLTokenCreate(resp http.ResponseWriter, req *http.Reques
|
||||||
return s.aclTokenSetInternal(req, "", true)
|
return s.aclTokenSetInternal(req, "", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *HTTPHandlers) ACLTokenGet(resp http.ResponseWriter, req *http.Request, tokenID string) (interface{}, error) {
|
func (s *HTTPHandlers) ACLTokenGet(resp http.ResponseWriter, req *http.Request, tokenAccessorID string) (interface{}, error) {
|
||||||
args := structs.ACLTokenGetRequest{
|
args := structs.ACLTokenGetRequest{
|
||||||
Datacenter: s.agent.config.Datacenter,
|
Datacenter: s.agent.config.Datacenter,
|
||||||
TokenID: tokenID,
|
TokenID: tokenAccessorID,
|
||||||
TokenIDType: structs.ACLTokenAccessor,
|
TokenIDType: structs.ACLTokenAccessor,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,11 +407,11 @@ func (s *HTTPHandlers) ACLTokenGet(resp http.ResponseWriter, req *http.Request,
|
||||||
return out.Token, nil
|
return out.Token, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *HTTPHandlers) ACLTokenSet(_ http.ResponseWriter, req *http.Request, tokenID string) (interface{}, error) {
|
func (s *HTTPHandlers) ACLTokenSet(_ http.ResponseWriter, req *http.Request, tokenAccessorID string) (interface{}, error) {
|
||||||
return s.aclTokenSetInternal(req, tokenID, false)
|
return s.aclTokenSetInternal(req, tokenAccessorID, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *HTTPHandlers) aclTokenSetInternal(req *http.Request, tokenID string, create bool) (interface{}, error) {
|
func (s *HTTPHandlers) aclTokenSetInternal(req *http.Request, tokenAccessorID string, create bool) (interface{}, error) {
|
||||||
args := structs.ACLTokenSetRequest{
|
args := structs.ACLTokenSetRequest{
|
||||||
Datacenter: s.agent.config.Datacenter,
|
Datacenter: s.agent.config.Datacenter,
|
||||||
Create: create,
|
Create: create,
|
||||||
|
@ -425,10 +425,8 @@ func (s *HTTPHandlers) aclTokenSetInternal(req *http.Request, tokenID string, cr
|
||||||
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: fmt.Sprintf("Token decoding failed: %v", err)}
|
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: fmt.Sprintf("Token decoding failed: %v", err)}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !create {
|
if !create && args.ACLToken.AccessorID != tokenAccessorID {
|
||||||
if args.ACLToken.AccessorID != tokenID {
|
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Token Accessor ID in URL and payload do not match"}
|
||||||
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Token Accessor ID in URL and payload do not match"}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var out structs.ACLToken
|
var out structs.ACLToken
|
||||||
|
@ -439,10 +437,10 @@ func (s *HTTPHandlers) aclTokenSetInternal(req *http.Request, tokenID string, cr
|
||||||
return &out, nil
|
return &out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *HTTPHandlers) ACLTokenDelete(resp http.ResponseWriter, req *http.Request, tokenID string) (interface{}, error) {
|
func (s *HTTPHandlers) ACLTokenDelete(resp http.ResponseWriter, req *http.Request, tokenAccessorID string) (interface{}, error) {
|
||||||
args := structs.ACLTokenDeleteRequest{
|
args := structs.ACLTokenDeleteRequest{
|
||||||
Datacenter: s.agent.config.Datacenter,
|
Datacenter: s.agent.config.Datacenter,
|
||||||
TokenID: tokenID,
|
TokenID: tokenAccessorID,
|
||||||
}
|
}
|
||||||
s.parseToken(req, &args.Token)
|
s.parseToken(req, &args.Token)
|
||||||
if err := s.parseEntMeta(req, &args.EnterpriseMeta); err != nil {
|
if err := s.parseEntMeta(req, &args.EnterpriseMeta); err != nil {
|
||||||
|
@ -456,7 +454,7 @@ func (s *HTTPHandlers) ACLTokenDelete(resp http.ResponseWriter, req *http.Reques
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *HTTPHandlers) ACLTokenClone(resp http.ResponseWriter, req *http.Request, tokenID string) (interface{}, error) {
|
func (s *HTTPHandlers) ACLTokenClone(resp http.ResponseWriter, req *http.Request, tokenAccessorID string) (interface{}, error) {
|
||||||
if s.checkACLDisabled() {
|
if s.checkACLDisabled() {
|
||||||
return nil, aclDisabled
|
return nil, aclDisabled
|
||||||
}
|
}
|
||||||
|
@ -475,7 +473,7 @@ func (s *HTTPHandlers) ACLTokenClone(resp http.ResponseWriter, req *http.Request
|
||||||
s.parseToken(req, &args.Token)
|
s.parseToken(req, &args.Token)
|
||||||
|
|
||||||
// Set this for the ID to clone
|
// Set this for the ID to clone
|
||||||
args.ACLToken.AccessorID = tokenID
|
args.ACLToken.AccessorID = tokenAccessorID
|
||||||
|
|
||||||
var out structs.ACLToken
|
var out structs.ACLToken
|
||||||
if err := s.agent.RPC(req.Context(), "ACL.TokenClone", args, &out); err != nil {
|
if err := s.agent.RPC(req.Context(), "ACL.TokenClone", args, &out); err != nil {
|
||||||
|
|
|
@ -37,7 +37,7 @@ type TestACLAgent struct {
|
||||||
|
|
||||||
// NewTestACLAgent does just enough so that all the code within agent/acl.go can work
|
// NewTestACLAgent does just enough so that all the code within agent/acl.go can work
|
||||||
// Basically it needs a local state for some of the vet* functions, a logger and a delegate.
|
// Basically it needs a local state for some of the vet* functions, a logger and a delegate.
|
||||||
// The key is that we are the delegate so we can control the ResolveToken responses
|
// The key is that we are the delegate so we can control the ResolveTokenSecret responses
|
||||||
func NewTestACLAgent(t *testing.T, name string, hcl string, resolveAuthz authzResolver, resolveIdent identResolver) *TestACLAgent {
|
func NewTestACLAgent(t *testing.T, name string, hcl string, resolveAuthz authzResolver, resolveIdent identResolver) *TestACLAgent {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
@ -89,9 +89,9 @@ func NewTestACLAgent(t *testing.T, name string, hcl string, resolveAuthz authzRe
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *TestACLAgent) ResolveToken(secretID string) (acl.Authorizer, error) {
|
func (a *TestACLAgent) ResolveTokenSecret(secretID string) (acl.Authorizer, error) {
|
||||||
if a.resolveAuthzFn == nil {
|
if a.resolveAuthzFn == nil {
|
||||||
return nil, fmt.Errorf("ResolveToken call is unexpected - no authz resolver callback set")
|
return nil, fmt.Errorf("ResolveTokenSecret call is unexpected - no authz resolver callback set")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, authz, err := a.resolveAuthzFn(secretID)
|
_, authz, err := a.resolveAuthzFn(secretID)
|
||||||
|
@ -99,7 +99,7 @@ func (a *TestACLAgent) ResolveToken(secretID string) (acl.Authorizer, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *TestACLAgent) ResolveTokenAndDefaultMeta(secretID string, entMeta *acl.EnterpriseMeta, authzContext *acl.AuthorizerContext) (resolver.Result, error) {
|
func (a *TestACLAgent) ResolveTokenAndDefaultMeta(secretID string, entMeta *acl.EnterpriseMeta, authzContext *acl.AuthorizerContext) (resolver.Result, error) {
|
||||||
authz, err := a.ResolveToken(secretID)
|
authz, err := a.ResolveTokenSecret(secretID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resolver.Result{}, err
|
return resolver.Result{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4418,7 +4418,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar(t *testing.T, extraHCL s
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
enableACL: true,
|
enableACL: true,
|
||||||
policies: ``, // No token rules means no valid token
|
policies: ``, // No policy means no valid token
|
||||||
wantNS: nil,
|
wantNS: nil,
|
||||||
wantErr: "Permission denied",
|
wantErr: "Permission denied",
|
||||||
},
|
},
|
||||||
|
|
|
@ -41,7 +41,7 @@ var ACLSummaries = []prometheus.SummaryDefinition{
|
||||||
|
|
||||||
// These must be kept in sync with the constants in command/agent/acl.go.
|
// These must be kept in sync with the constants in command/agent/acl.go.
|
||||||
const (
|
const (
|
||||||
// anonymousToken is the token ID we re-write to if there is no token ID
|
// anonymousToken is the token SecretID we re-write to if there is no token ID
|
||||||
// provided.
|
// provided.
|
||||||
anonymousToken = "anonymous"
|
anonymousToken = "anonymous"
|
||||||
|
|
||||||
|
@ -993,35 +993,35 @@ func (r *ACLResolver) resolveLocallyManagedToken(token string) (structs.ACLIdent
|
||||||
return r.resolveLocallyManagedEnterpriseToken(token)
|
return r.resolveLocallyManagedEnterpriseToken(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolveToken to an acl.Authorizer and structs.ACLIdentity. The acl.Authorizer
|
// ResolveTokenSecret to an acl.Authorizer and structs.ACLIdentity. The acl.Authorizer
|
||||||
// can be used to check permissions granted to the token, and the ACLIdentity
|
// can be used to check permissions granted to the token using its secret, and the
|
||||||
// describes the token and any defaults applied to it.
|
// ACLIdentity describes the token and any defaults applied to it.
|
||||||
func (r *ACLResolver) ResolveToken(token string) (resolver.Result, error) {
|
func (r *ACLResolver) ResolveTokenSecret(tokenSecretID string) (resolver.Result, error) {
|
||||||
if !r.ACLsEnabled() {
|
if !r.ACLsEnabled() {
|
||||||
return resolver.Result{Authorizer: acl.ManageAll()}, nil
|
return resolver.Result{Authorizer: acl.ManageAll()}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if acl.RootAuthorizer(token) != nil {
|
if acl.RootAuthorizer(tokenSecretID) != nil {
|
||||||
return resolver.Result{}, acl.ErrRootDenied
|
return resolver.Result{}, acl.ErrRootDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle the anonymous token
|
// handle the anonymous token
|
||||||
if token == "" {
|
if tokenSecretID == "" {
|
||||||
token = anonymousToken
|
tokenSecretID = anonymousToken
|
||||||
}
|
}
|
||||||
|
|
||||||
if ident, authz, ok := r.resolveLocallyManagedToken(token); ok {
|
if ident, authz, ok := r.resolveLocallyManagedToken(tokenSecretID); ok {
|
||||||
return resolver.Result{Authorizer: authz, ACLIdentity: ident}, nil
|
return resolver.Result{Authorizer: authz, ACLIdentity: ident}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
defer metrics.MeasureSince([]string{"acl", "ResolveToken"}, time.Now())
|
defer metrics.MeasureSince([]string{"acl", "ResolveToken"}, time.Now())
|
||||||
|
|
||||||
identity, policies, err := r.resolveTokenToIdentityAndPolicies(token)
|
identity, policies, err := r.resolveTokenToIdentityAndPolicies(tokenSecretID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.handleACLDisabledError(err)
|
r.handleACLDisabledError(err)
|
||||||
if IsACLRemoteError(err) {
|
if IsACLRemoteError(err) {
|
||||||
r.logger.Error("Error resolving token", "error", err)
|
r.logger.Error("Error resolving token", "error", err)
|
||||||
ident := &missingIdentity{reason: "primary-dc-down", token: token}
|
ident := &missingIdentity{reason: "primary-dc-down", token: tokenSecretID}
|
||||||
return resolver.Result{Authorizer: r.down, ACLIdentity: ident}, nil
|
return resolver.Result{Authorizer: r.down, ACLIdentity: ident}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1074,11 +1074,11 @@ func (r *ACLResolver) ACLsEnabled() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ACLResolver) ResolveTokenAndDefaultMeta(
|
func (r *ACLResolver) ResolveTokenAndDefaultMeta(
|
||||||
token string,
|
tokenSecretID string,
|
||||||
entMeta *acl.EnterpriseMeta,
|
entMeta *acl.EnterpriseMeta,
|
||||||
authzContext *acl.AuthorizerContext,
|
authzContext *acl.AuthorizerContext,
|
||||||
) (resolver.Result, error) {
|
) (resolver.Result, error) {
|
||||||
result, err := r.ResolveToken(token)
|
result, err := r.ResolveTokenSecret(tokenSecretID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resolver.Result{}, err
|
return resolver.Result{}, err
|
||||||
}
|
}
|
||||||
|
@ -1119,9 +1119,9 @@ func filterACLWithAuthorizer(logger hclog.Logger, authorizer acl.Authorizer, sub
|
||||||
// filterACL uses the ACLResolver to resolve the token in an acl.Authorizer,
|
// filterACL uses the ACLResolver to resolve the token in an acl.Authorizer,
|
||||||
// then uses the acl.Authorizer to filter subj. Any entities in subj that are
|
// then uses the acl.Authorizer to filter subj. Any entities in subj that are
|
||||||
// not authorized for read access will be removed from subj.
|
// not authorized for read access will be removed from subj.
|
||||||
func filterACL(r *ACLResolver, token string, subj interface{}) error {
|
func filterACL(r *ACLResolver, tokenSecretID string, subj interface{}) error {
|
||||||
// Get the ACL from the token
|
// Get the ACL from the token
|
||||||
authorizer, err := r.ResolveToken(token)
|
authorizer, err := r.ResolveTokenSecret(tokenSecretID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -703,7 +703,7 @@ func (a *ACL) TokenBatchRead(args *structs.ACLTokenBatchGetRequest, reply *struc
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
authz, err := a.srv.ResolveToken(args.Token)
|
authz, err := a.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -796,7 +796,7 @@ func (a *ACL) PolicyBatchRead(args *structs.ACLPolicyBatchGetRequest, reply *str
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
authz, err := a.srv.ResolveToken(args.Token)
|
authz, err := a.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1182,7 +1182,7 @@ func (a *ACL) RoleBatchRead(args *structs.ACLRoleBatchGetRequest, reply *structs
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
authz, err := a.srv.ResolveToken(args.Token)
|
authz, err := a.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -2115,7 +2115,7 @@ func (a *ACL) Authorize(args *structs.RemoteACLAuthorizationRequest, reply *[]st
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
authz, err := a.srv.ResolveToken(args.Token)
|
authz, err := a.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -526,7 +526,7 @@ func TestACLEndpoint_TokenSet(t *testing.T) {
|
||||||
|
|
||||||
a := ACL{srv: srv}
|
a := ACL{srv: srv}
|
||||||
|
|
||||||
var tokenID string
|
var accessorID string
|
||||||
|
|
||||||
t.Run("Create it", func(t *testing.T) {
|
t.Run("Create it", func(t *testing.T) {
|
||||||
req := structs.ACLTokenSetRequest{
|
req := structs.ACLTokenSetRequest{
|
||||||
|
@ -563,7 +563,7 @@ func TestACLEndpoint_TokenSet(t *testing.T) {
|
||||||
require.Equal(t, "foo", token.NodeIdentities[0].NodeName)
|
require.Equal(t, "foo", token.NodeIdentities[0].NodeName)
|
||||||
require.Equal(t, "dc1", token.NodeIdentities[0].Datacenter)
|
require.Equal(t, "dc1", token.NodeIdentities[0].Datacenter)
|
||||||
|
|
||||||
tokenID = token.AccessorID
|
accessorID = token.AccessorID
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Update it", func(t *testing.T) {
|
t.Run("Update it", func(t *testing.T) {
|
||||||
|
@ -571,7 +571,7 @@ func TestACLEndpoint_TokenSet(t *testing.T) {
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
ACLToken: structs.ACLToken{
|
ACLToken: structs.ACLToken{
|
||||||
Description: "new-description",
|
Description: "new-description",
|
||||||
AccessorID: tokenID,
|
AccessorID: accessorID,
|
||||||
},
|
},
|
||||||
WriteRequest: structs.WriteRequest{Token: TestDefaultInitialManagementToken},
|
WriteRequest: structs.WriteRequest{Token: TestDefaultInitialManagementToken},
|
||||||
}
|
}
|
||||||
|
@ -1085,7 +1085,7 @@ func TestACLEndpoint_TokenSet(t *testing.T) {
|
||||||
require.Equal(t, token.AccessorID, resp.AccessorID)
|
require.Equal(t, token.AccessorID, resp.AccessorID)
|
||||||
requireTimeEquals(t, &expectExpTime, resp.ExpirationTime)
|
requireTimeEquals(t, &expectExpTime, resp.ExpirationTime)
|
||||||
|
|
||||||
tokenID = token.AccessorID
|
accessorID = token.AccessorID
|
||||||
})
|
})
|
||||||
|
|
||||||
var expTime time.Time
|
var expTime time.Time
|
||||||
|
@ -1118,7 +1118,7 @@ func TestACLEndpoint_TokenSet(t *testing.T) {
|
||||||
require.Equal(t, token.AccessorID, resp.AccessorID)
|
require.Equal(t, token.AccessorID, resp.AccessorID)
|
||||||
requireTimeEquals(t, &expTime, resp.ExpirationTime)
|
requireTimeEquals(t, &expTime, resp.ExpirationTime)
|
||||||
|
|
||||||
tokenID = token.AccessorID
|
accessorID = token.AccessorID
|
||||||
})
|
})
|
||||||
|
|
||||||
// do not insert another test at this point: these tests need to be serial
|
// do not insert another test at this point: these tests need to be serial
|
||||||
|
@ -1128,7 +1128,7 @@ func TestACLEndpoint_TokenSet(t *testing.T) {
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
ACLToken: structs.ACLToken{
|
ACLToken: structs.ACLToken{
|
||||||
Description: "new-description",
|
Description: "new-description",
|
||||||
AccessorID: tokenID,
|
AccessorID: accessorID,
|
||||||
ExpirationTime: timePointer(expTime.Add(-1 * time.Second)),
|
ExpirationTime: timePointer(expTime.Add(-1 * time.Second)),
|
||||||
},
|
},
|
||||||
WriteRequest: structs.WriteRequest{Token: TestDefaultInitialManagementToken},
|
WriteRequest: structs.WriteRequest{Token: TestDefaultInitialManagementToken},
|
||||||
|
@ -1147,7 +1147,7 @@ func TestACLEndpoint_TokenSet(t *testing.T) {
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
ACLToken: structs.ACLToken{
|
ACLToken: structs.ACLToken{
|
||||||
Description: "new-description-1",
|
Description: "new-description-1",
|
||||||
AccessorID: tokenID,
|
AccessorID: accessorID,
|
||||||
},
|
},
|
||||||
WriteRequest: structs.WriteRequest{Token: TestDefaultInitialManagementToken},
|
WriteRequest: structs.WriteRequest{Token: TestDefaultInitialManagementToken},
|
||||||
}
|
}
|
||||||
|
@ -1174,7 +1174,7 @@ func TestACLEndpoint_TokenSet(t *testing.T) {
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
ACLToken: structs.ACLToken{
|
ACLToken: structs.ACLToken{
|
||||||
Description: "new-description-2",
|
Description: "new-description-2",
|
||||||
AccessorID: tokenID,
|
AccessorID: accessorID,
|
||||||
ExpirationTime: &expTime,
|
ExpirationTime: &expTime,
|
||||||
},
|
},
|
||||||
WriteRequest: structs.WriteRequest{Token: TestDefaultInitialManagementToken},
|
WriteRequest: structs.WriteRequest{Token: TestDefaultInitialManagementToken},
|
||||||
|
|
|
@ -313,10 +313,10 @@ func (s *Server) updateLocalACLType(ctx context.Context, logger hclog.Logger, tr
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) fetchACLTokensBatch(tokenIDs []string) (*structs.ACLTokenBatchResponse, error) {
|
func (s *Server) fetchACLTokensBatch(tokenAccessorIDs []string) (*structs.ACLTokenBatchResponse, error) {
|
||||||
req := structs.ACLTokenBatchGetRequest{
|
req := structs.ACLTokenBatchGetRequest{
|
||||||
Datacenter: s.config.PrimaryDatacenter,
|
Datacenter: s.config.PrimaryDatacenter,
|
||||||
AccessorIDs: tokenIDs,
|
AccessorIDs: tokenAccessorIDs,
|
||||||
QueryOptions: structs.QueryOptions{
|
QueryOptions: structs.QueryOptions{
|
||||||
AllowStale: true,
|
AllowStale: true,
|
||||||
Token: s.tokens.ReplicationToken(),
|
Token: s.tokens.ReplicationToken(),
|
||||||
|
|
|
@ -65,13 +65,13 @@ func verifyAuthorizerChain(t *testing.T, expected resolver.Result, actual resolv
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveTokenAsync(r *ACLResolver, token string, ch chan *asyncResolutionResult) {
|
func resolveTokenAsync(r *ACLResolver, token string, ch chan *asyncResolutionResult) {
|
||||||
authz, err := r.ResolveToken(token)
|
authz, err := r.ResolveTokenSecret(token)
|
||||||
ch <- &asyncResolutionResult{authz: authz, err: err}
|
ch <- &asyncResolutionResult{authz: authz, err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveToken(t *testing.T, r *ACLResolver, token string) acl.Authorizer {
|
func resolveTokenSecret(t *testing.T, r *ACLResolver, token string) acl.Authorizer {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
authz, err := r.ResolveToken(token)
|
authz, err := r.ResolveTokenSecret(token)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return authz
|
return authz
|
||||||
}
|
}
|
||||||
|
@ -732,7 +732,7 @@ func TestACLResolver_Disabled(t *testing.T) {
|
||||||
|
|
||||||
r := newTestACLResolver(t, delegate, nil)
|
r := newTestACLResolver(t, delegate, nil)
|
||||||
|
|
||||||
authz, err := r.ResolveToken("does not exist")
|
authz, err := r.ResolveTokenSecret("does not exist")
|
||||||
require.Equal(t, resolver.Result{Authorizer: acl.ManageAll()}, authz)
|
require.Equal(t, resolver.Result{Authorizer: acl.ManageAll()}, authz)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
@ -747,19 +747,19 @@ func TestACLResolver_ResolveRootACL(t *testing.T) {
|
||||||
r := newTestACLResolver(t, delegate, nil)
|
r := newTestACLResolver(t, delegate, nil)
|
||||||
|
|
||||||
t.Run("Allow", func(t *testing.T) {
|
t.Run("Allow", func(t *testing.T) {
|
||||||
_, err := r.ResolveToken("allow")
|
_, err := r.ResolveTokenSecret("allow")
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.True(t, acl.IsErrRootDenied(err))
|
require.True(t, acl.IsErrRootDenied(err))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Deny", func(t *testing.T) {
|
t.Run("Deny", func(t *testing.T) {
|
||||||
_, err := r.ResolveToken("deny")
|
_, err := r.ResolveTokenSecret("deny")
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.True(t, acl.IsErrRootDenied(err))
|
require.True(t, acl.IsErrRootDenied(err))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Manage", func(t *testing.T) {
|
t.Run("Manage", func(t *testing.T) {
|
||||||
_, err := r.ResolveToken("manage")
|
_, err := r.ResolveTokenSecret("manage")
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.True(t, acl.IsErrRootDenied(err))
|
require.True(t, acl.IsErrRootDenied(err))
|
||||||
})
|
})
|
||||||
|
@ -805,7 +805,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLDownPolicy = "deny"
|
config.Config.ACLDownPolicy = "deny"
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("foo")
|
authz, err := r.ResolveTokenSecret("foo")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
expected := resolver.Result{
|
expected := resolver.Result{
|
||||||
|
@ -833,7 +833,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLDownPolicy = "allow"
|
config.Config.ACLDownPolicy = "allow"
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("foo")
|
authz, err := r.ResolveTokenSecret("foo")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
expected := resolver.Result{
|
expected := resolver.Result{
|
||||||
|
@ -862,7 +862,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLRoleTTL = 0
|
config.Config.ACLRoleTTL = 0
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("found")
|
authz, err := r.ResolveTokenSecret("found")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
@ -871,7 +871,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
requirePolicyCached(t, r, "dc2-key-wr", true, "cached") // from "found" token
|
requirePolicyCached(t, r, "dc2-key-wr", true, "cached") // from "found" token
|
||||||
|
|
||||||
// policy cache expired - so we will fail to resolve that policy and use the default policy only
|
// policy cache expired - so we will fail to resolve that policy and use the default policy only
|
||||||
authz2, err := r.ResolveToken("found")
|
authz2, err := r.ResolveTokenSecret("found")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz2)
|
require.NotNil(t, authz2)
|
||||||
require.NotEqual(t, authz, authz2)
|
require.NotEqual(t, authz, authz2)
|
||||||
|
@ -899,13 +899,13 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLRoleTTL = 0
|
config.Config.ACLRoleTTL = 0
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("found-role")
|
authz, err := r.ResolveTokenSecret("found-role")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
|
||||||
// role cache expired - so we will fail to resolve that role and use the default policy only
|
// role cache expired - so we will fail to resolve that role and use the default policy only
|
||||||
authz2, err := r.ResolveToken("found-role")
|
authz2, err := r.ResolveTokenSecret("found-role")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz2)
|
require.NotNil(t, authz2)
|
||||||
require.False(t, authz == authz2)
|
require.False(t, authz == authz2)
|
||||||
|
@ -928,14 +928,14 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLTokenTTL = 0
|
config.Config.ACLTokenTTL = 0
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("found")
|
authz, err := r.ResolveTokenSecret("found")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
|
||||||
requireIdentityCached(t, r, "found", true, "cached")
|
requireIdentityCached(t, r, "found", true, "cached")
|
||||||
|
|
||||||
authz2, err := r.ResolveToken("found")
|
authz2, err := r.ResolveTokenSecret("found")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz2)
|
require.NotNil(t, authz2)
|
||||||
verifyAuthorizerChain(t, authz, authz2)
|
verifyAuthorizerChain(t, authz, authz2)
|
||||||
|
@ -957,7 +957,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLDownPolicy = "extend-cache"
|
config.Config.ACLDownPolicy = "extend-cache"
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("not-found")
|
authz, err := r.ResolveTokenSecret("not-found")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Deny, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Deny, authz.NodeWrite("foo", nil))
|
||||||
|
@ -979,14 +979,14 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLTokenTTL = 0
|
config.Config.ACLTokenTTL = 0
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("found-role")
|
authz, err := r.ResolveTokenSecret("found-role")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
|
||||||
requireIdentityCached(t, r, "found-role", true, "still cached")
|
requireIdentityCached(t, r, "found-role", true, "still cached")
|
||||||
|
|
||||||
authz2, err := r.ResolveToken("found-role")
|
authz2, err := r.ResolveTokenSecret("found-role")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz2)
|
require.NotNil(t, authz2)
|
||||||
// testing pointer equality - these will be the same object because it is cached.
|
// testing pointer equality - these will be the same object because it is cached.
|
||||||
|
@ -1011,7 +1011,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLRoleTTL = 0
|
config.Config.ACLRoleTTL = 0
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("found")
|
authz, err := r.ResolveTokenSecret("found")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1020,7 +1020,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
requirePolicyCached(t, r, "dc2-key-wr", true, "cached") // from "found" token
|
requirePolicyCached(t, r, "dc2-key-wr", true, "cached") // from "found" token
|
||||||
|
|
||||||
// Will just use the policy cache
|
// Will just use the policy cache
|
||||||
authz2, err := r.ResolveToken("found")
|
authz2, err := r.ResolveTokenSecret("found")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz2)
|
require.NotNil(t, authz2)
|
||||||
verifyAuthorizerChain(t, authz, authz2)
|
verifyAuthorizerChain(t, authz, authz2)
|
||||||
|
@ -1048,13 +1048,13 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLRoleTTL = 0
|
config.Config.ACLRoleTTL = 0
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("found-role")
|
authz, err := r.ResolveTokenSecret("found-role")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
|
||||||
// Will just use the policy cache
|
// Will just use the policy cache
|
||||||
authz2, err := r.ResolveToken("found-role")
|
authz2, err := r.ResolveTokenSecret("found-role")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz2)
|
require.NotNil(t, authz2)
|
||||||
verifyAuthorizerChain(t, authz, authz2)
|
verifyAuthorizerChain(t, authz, authz2)
|
||||||
|
@ -1081,7 +1081,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLRoleTTL = 0
|
config.Config.ACLRoleTTL = 0
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("found")
|
authz, err := r.ResolveTokenSecret("found")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1090,7 +1090,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
requirePolicyCached(t, r, "dc2-key-wr", true, "cached") // from "found" token
|
requirePolicyCached(t, r, "dc2-key-wr", true, "cached") // from "found" token
|
||||||
|
|
||||||
// The identity should have been cached so this should still be valid
|
// The identity should have been cached so this should still be valid
|
||||||
authz2, err := r.ResolveToken("found")
|
authz2, err := r.ResolveTokenSecret("found")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz2)
|
require.NotNil(t, authz2)
|
||||||
// testing pointer equality - these will be the same object because it is cached.
|
// testing pointer equality - these will be the same object because it is cached.
|
||||||
|
@ -1099,7 +1099,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
|
|
||||||
// the go routine spawned will eventually return with a authz that doesn't have the policy
|
// the go routine spawned will eventually return with a authz that doesn't have the policy
|
||||||
retry.Run(t, func(t *retry.R) {
|
retry.Run(t, func(t *retry.R) {
|
||||||
authz3, err := r.ResolveToken("found")
|
authz3, err := r.ResolveTokenSecret("found")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, authz3)
|
assert.NotNil(t, authz3)
|
||||||
assert.Equal(t, acl.Deny, authz3.NodeWrite("foo", nil))
|
assert.Equal(t, acl.Deny, authz3.NodeWrite("foo", nil))
|
||||||
|
@ -1129,13 +1129,13 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLRoleTTL = 0
|
config.Config.ACLRoleTTL = 0
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("found-role")
|
authz, err := r.ResolveTokenSecret("found-role")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
|
||||||
// The identity should have been cached so this should still be valid
|
// The identity should have been cached so this should still be valid
|
||||||
authz2, err := r.ResolveToken("found-role")
|
authz2, err := r.ResolveTokenSecret("found-role")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz2)
|
require.NotNil(t, authz2)
|
||||||
// testing pointer equality - these will be the same object because it is cached.
|
// testing pointer equality - these will be the same object because it is cached.
|
||||||
|
@ -1144,7 +1144,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
|
|
||||||
// the go routine spawned will eventually return with a authz that doesn't have the policy
|
// the go routine spawned will eventually return with a authz that doesn't have the policy
|
||||||
retry.Run(t, func(t *retry.R) {
|
retry.Run(t, func(t *retry.R) {
|
||||||
authz3, err := r.ResolveToken("found-role")
|
authz3, err := r.ResolveTokenSecret("found-role")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, authz3)
|
assert.NotNil(t, authz3)
|
||||||
assert.Equal(t, acl.Deny, authz3.NodeWrite("foo", nil))
|
assert.Equal(t, acl.Deny, authz3.NodeWrite("foo", nil))
|
||||||
|
@ -1170,7 +1170,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLRoleTTL = 0
|
config.Config.ACLRoleTTL = 0
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("found")
|
authz, err := r.ResolveTokenSecret("found")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1178,7 +1178,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
requirePolicyCached(t, r, "node-wr", true, "cached") // from "found" token
|
requirePolicyCached(t, r, "node-wr", true, "cached") // from "found" token
|
||||||
requirePolicyCached(t, r, "dc2-key-wr", true, "cached") // from "found" token
|
requirePolicyCached(t, r, "dc2-key-wr", true, "cached") // from "found" token
|
||||||
|
|
||||||
authz2, err := r.ResolveToken("found")
|
authz2, err := r.ResolveTokenSecret("found")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz2)
|
require.NotNil(t, authz2)
|
||||||
// testing pointer equality - these will be the same object because it is cached.
|
// testing pointer equality - these will be the same object because it is cached.
|
||||||
|
@ -1206,7 +1206,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLRoleTTL = 0
|
config.Config.ACLRoleTTL = 0
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("found-role")
|
authz, err := r.ResolveTokenSecret("found-role")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1214,7 +1214,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
requirePolicyCached(t, r, "node-wr", true, "still cached") // from "found" token
|
requirePolicyCached(t, r, "node-wr", true, "still cached") // from "found" token
|
||||||
requirePolicyCached(t, r, "dc2-key-wr", true, "still cached") // from "found" token
|
requirePolicyCached(t, r, "dc2-key-wr", true, "still cached") // from "found" token
|
||||||
|
|
||||||
authz2, err := r.ResolveToken("found-role")
|
authz2, err := r.ResolveTokenSecret("found-role")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz2)
|
require.NotNil(t, authz2)
|
||||||
// testing pointer equality - these will be the same object because it is cached.
|
// testing pointer equality - these will be the same object because it is cached.
|
||||||
|
@ -1238,7 +1238,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
config.Config.ACLTokenTTL = 0
|
config.Config.ACLTokenTTL = 0
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("found")
|
authz, err := r.ResolveTokenSecret("found")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1246,7 +1246,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
requireIdentityCached(t, r, "found", true, "cached")
|
requireIdentityCached(t, r, "found", true, "cached")
|
||||||
|
|
||||||
// The identity should have been cached so this should still be valid
|
// The identity should have been cached so this should still be valid
|
||||||
authz2, err := r.ResolveToken("found")
|
authz2, err := r.ResolveTokenSecret("found")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz2)
|
require.NotNil(t, authz2)
|
||||||
verifyAuthorizerChain(t, authz, authz2)
|
verifyAuthorizerChain(t, authz, authz2)
|
||||||
|
@ -1254,7 +1254,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
|
|
||||||
// the go routine spawned will eventually return and this will be a not found error
|
// the go routine spawned will eventually return and this will be a not found error
|
||||||
retry.Run(t, func(t *retry.R) {
|
retry.Run(t, func(t *retry.R) {
|
||||||
_, err := r.ResolveToken("found")
|
_, err := r.ResolveTokenSecret("found")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, acl.IsErrNotFound(err))
|
assert.True(t, acl.IsErrNotFound(err))
|
||||||
})
|
})
|
||||||
|
@ -1305,7 +1305,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Prime the standard caches.
|
// Prime the standard caches.
|
||||||
authz, err := r.ResolveToken(secretID)
|
authz, err := r.ResolveTokenSecret(secretID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1319,7 +1319,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
// during token resolve.
|
// during token resolve.
|
||||||
r.cache.RemovePolicy("dc2-key-wr")
|
r.cache.RemovePolicy("dc2-key-wr")
|
||||||
|
|
||||||
_, err = r.ResolveToken(secretID)
|
_, err = r.ResolveTokenSecret(secretID)
|
||||||
require.True(t, acl.IsErrNotFound(err))
|
require.True(t, acl.IsErrNotFound(err))
|
||||||
|
|
||||||
requireIdentityCached(t, r, secretID, false, "identity not found cached")
|
requireIdentityCached(t, r, secretID, false, "identity not found cached")
|
||||||
|
@ -1365,7 +1365,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Prime the standard caches.
|
// Prime the standard caches.
|
||||||
authz, err := r.ResolveToken(secretID)
|
authz, err := r.ResolveTokenSecret(secretID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1379,7 +1379,7 @@ func TestACLResolver_DownPolicy(t *testing.T) {
|
||||||
// during token resolve.
|
// during token resolve.
|
||||||
r.cache.RemovePolicy("dc2-key-wr")
|
r.cache.RemovePolicy("dc2-key-wr")
|
||||||
|
|
||||||
_, err = r.ResolveToken(secretID)
|
_, err = r.ResolveTokenSecret(secretID)
|
||||||
require.True(t, acl.IsErrPermissionDenied(err))
|
require.True(t, acl.IsErrPermissionDenied(err))
|
||||||
|
|
||||||
require.Nil(t, r.cache.GetIdentityWithSecretToken(secretID), "identity not stored at all")
|
require.Nil(t, r.cache.GetIdentityWithSecretToken(secretID), "identity not stored at all")
|
||||||
|
@ -1402,7 +1402,7 @@ func TestACLResolver_DatacenterScoping(t *testing.T) {
|
||||||
}
|
}
|
||||||
r := newTestACLResolver(t, delegate, nil)
|
r := newTestACLResolver(t, delegate, nil)
|
||||||
|
|
||||||
authz, err := r.ResolveToken("found")
|
authz, err := r.ResolveTokenSecret("found")
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, acl.Deny, authz.ACLRead(nil))
|
require.Equal(t, acl.Deny, authz.ACLRead(nil))
|
||||||
|
@ -1424,7 +1424,7 @@ func TestACLResolver_DatacenterScoping(t *testing.T) {
|
||||||
config.Config.Datacenter = "dc2"
|
config.Config.Datacenter = "dc2"
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken("found")
|
authz, err := r.ResolveTokenSecret("found")
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, acl.Deny, authz.ACLRead(nil))
|
require.Equal(t, acl.Deny, authz.ACLRead(nil))
|
||||||
|
@ -1505,7 +1505,7 @@ func TestACLResolver_Client(t *testing.T) {
|
||||||
// Must use the token secret here in order for the cached identity
|
// Must use the token secret here in order for the cached identity
|
||||||
// to be removed properly. Many other tests just resolve some other
|
// to be removed properly. Many other tests just resolve some other
|
||||||
// random name and it wont matter but this one cannot.
|
// random name and it wont matter but this one cannot.
|
||||||
authz, err := r.ResolveToken("a1a54629-5050-4d17-8a4e-560d2423f835")
|
authz, err := r.ResolveTokenSecret("a1a54629-5050-4d17-8a4e-560d2423f835")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1522,7 +1522,7 @@ func TestACLResolver_Client(t *testing.T) {
|
||||||
// then the policy will be resolved but resolution will return ACL not found
|
// then the policy will be resolved but resolution will return ACL not found
|
||||||
// resolution will stop with the not found error (even though we still have the
|
// resolution will stop with the not found error (even though we still have the
|
||||||
// policies within the cache)
|
// policies within the cache)
|
||||||
_, err = r.ResolveToken("a1a54629-5050-4d17-8a4e-560d2423f835")
|
_, err = r.ResolveTokenSecret("a1a54629-5050-4d17-8a4e-560d2423f835")
|
||||||
require.EqualError(t, err, acl.ErrNotFound.Error())
|
require.EqualError(t, err, acl.ErrNotFound.Error())
|
||||||
|
|
||||||
require.True(t, modified)
|
require.True(t, modified)
|
||||||
|
@ -1672,7 +1672,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
|
|
||||||
runTwiceAndReset("Missing Identity", func(t *testing.T) {
|
runTwiceAndReset("Missing Identity", func(t *testing.T) {
|
||||||
delegate.UseTestLocalData(nil)
|
delegate.UseTestLocalData(nil)
|
||||||
_, err := r.ResolveToken("doesn't exist")
|
_, err := r.ResolveTokenSecret("doesn't exist")
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.True(t, acl.IsErrNotFound(err))
|
require.True(t, acl.IsErrNotFound(err))
|
||||||
})
|
})
|
||||||
|
@ -1696,7 +1696,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
authz := resolveToken(t, r, "missing-policy")
|
authz := resolveTokenSecret(t, r, "missing-policy")
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.ACLRead(nil))
|
require.Equal(t, acl.Allow, authz.ACLRead(nil))
|
||||||
require.Equal(t, acl.Deny, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Deny, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1729,7 +1729,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
authz := resolveToken(t, r, "missing-role")
|
authz := resolveTokenSecret(t, r, "missing-role")
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.ACLRead(nil))
|
require.Equal(t, acl.Allow, authz.ACLRead(nil))
|
||||||
require.Equal(t, acl.Deny, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Deny, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1763,7 +1763,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
authz := resolveToken(t, r, "missing-policy-on-role")
|
authz := resolveTokenSecret(t, r, "missing-policy-on-role")
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.ACLRead(nil))
|
require.Equal(t, acl.Allow, authz.ACLRead(nil))
|
||||||
require.Equal(t, acl.Deny, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Deny, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1796,7 +1796,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
authz := resolveToken(t, r, "found")
|
authz := resolveTokenSecret(t, r, "found")
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Deny, authz.ACLRead(nil))
|
require.Equal(t, acl.Deny, authz.ACLRead(nil))
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1837,7 +1837,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
authz := resolveToken(t, r, "found-role")
|
authz := resolveTokenSecret(t, r, "found-role")
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Deny, authz.ACLRead(nil))
|
require.Equal(t, acl.Deny, authz.ACLRead(nil))
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1889,7 +1889,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
authz := resolveToken(t, r, "found-policy-and-role")
|
authz := resolveTokenSecret(t, r, "found-policy-and-role")
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Deny, authz.ACLRead(nil))
|
require.Equal(t, acl.Deny, authz.ACLRead(nil))
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("foo", nil))
|
||||||
|
@ -1921,7 +1921,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
authz := resolveToken(t, r, "found-role-node-identity")
|
authz := resolveTokenSecret(t, r, "found-role-node-identity")
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.NodeWrite("test-node", nil))
|
require.Equal(t, acl.Allow, authz.NodeWrite("test-node", nil))
|
||||||
require.Equal(t, acl.Deny, authz.NodeWrite("test-node-dc2", nil))
|
require.Equal(t, acl.Deny, authz.NodeWrite("test-node-dc2", nil))
|
||||||
|
@ -1981,7 +1981,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
// to verify that the keys for caching synthetic policies don't bleed
|
// to verify that the keys for caching synthetic policies don't bleed
|
||||||
// over between each other.
|
// over between each other.
|
||||||
t.Run("synthetic-policy-1", func(t *testing.T) { // service identity
|
t.Run("synthetic-policy-1", func(t *testing.T) { // service identity
|
||||||
authz, err := r.ResolveToken("found-synthetic-policy-1")
|
authz, err := r.ResolveTokenSecret("found-synthetic-policy-1")
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
// spot check some random perms
|
// spot check some random perms
|
||||||
|
@ -1995,7 +1995,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
require.Equal(t, acl.Allow, authz.NodeRead("any-node", nil))
|
require.Equal(t, acl.Allow, authz.NodeRead("any-node", nil))
|
||||||
})
|
})
|
||||||
t.Run("synthetic-policy-2", func(t *testing.T) { // service identity
|
t.Run("synthetic-policy-2", func(t *testing.T) { // service identity
|
||||||
authz, err := r.ResolveToken("found-synthetic-policy-2")
|
authz, err := r.ResolveTokenSecret("found-synthetic-policy-2")
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
// spot check some random perms
|
// spot check some random perms
|
||||||
|
@ -2009,7 +2009,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
require.Equal(t, acl.Allow, authz.NodeRead("any-node", nil))
|
require.Equal(t, acl.Allow, authz.NodeRead("any-node", nil))
|
||||||
})
|
})
|
||||||
t.Run("synthetic-policy-3", func(t *testing.T) { // node identity
|
t.Run("synthetic-policy-3", func(t *testing.T) { // node identity
|
||||||
authz, err := r.ResolveToken("found-synthetic-policy-3")
|
authz, err := r.ResolveTokenSecret("found-synthetic-policy-3")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
|
|
||||||
|
@ -2025,7 +2025,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
require.Equal(t, acl.Deny, authz.NodeWrite("test-node-dc2", nil))
|
require.Equal(t, acl.Deny, authz.NodeWrite("test-node-dc2", nil))
|
||||||
})
|
})
|
||||||
t.Run("synthetic-policy-4", func(t *testing.T) { // node identity
|
t.Run("synthetic-policy-4", func(t *testing.T) { // node identity
|
||||||
authz, err := r.ResolveToken("found-synthetic-policy-4")
|
authz, err := r.ResolveTokenSecret("found-synthetic-policy-4")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
|
|
||||||
|
@ -2060,7 +2060,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
authz, err := r.ResolveToken("")
|
authz, err := r.ResolveTokenSecret("")
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, acl.Deny, authz.ACLRead(nil))
|
require.Equal(t, acl.Deny, authz.ACLRead(nil))
|
||||||
|
@ -2084,7 +2084,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
authz, err := r.ResolveToken("with-intentions")
|
authz, err := r.ResolveTokenSecret("with-intentions")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.ServiceRead("", nil))
|
require.Equal(t, acl.Allow, authz.ServiceRead("", nil))
|
||||||
|
@ -2165,7 +2165,7 @@ func TestACLResolver_AgentRecovery(t *testing.T) {
|
||||||
|
|
||||||
tokens.UpdateAgentRecoveryToken("9a184a11-5599-459e-b71a-550e5f9a5a23", token.TokenSourceConfig)
|
tokens.UpdateAgentRecoveryToken("9a184a11-5599-459e-b71a-550e5f9a5a23", token.TokenSourceConfig)
|
||||||
|
|
||||||
authz, err := r.ResolveToken("9a184a11-5599-459e-b71a-550e5f9a5a23")
|
authz, err := r.ResolveTokenSecret("9a184a11-5599-459e-b71a-550e5f9a5a23")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz.ACLIdentity)
|
require.NotNil(t, authz.ACLIdentity)
|
||||||
require.Equal(t, "agent-recovery:foo", authz.ACLIdentity.ID())
|
require.Equal(t, "agent-recovery:foo", authz.ACLIdentity.ID())
|
||||||
|
@ -2189,7 +2189,7 @@ func TestACLResolver_ServerManagementToken(t *testing.T) {
|
||||||
cfg.Config.NodeName = "foo"
|
cfg.Config.NodeName = "foo"
|
||||||
})
|
})
|
||||||
|
|
||||||
authz, err := r.ResolveToken(testToken)
|
authz, err := r.ResolveTokenSecret(testToken)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz.ACLIdentity)
|
require.NotNil(t, authz.ACLIdentity)
|
||||||
require.Equal(t, structs.ServerManagementTokenAccessorID, authz.ACLIdentity.ID())
|
require.Equal(t, structs.ServerManagementTokenAccessorID, authz.ACLIdentity.ID())
|
||||||
|
@ -2292,7 +2292,7 @@ func TestACLResolver_ResolveToken_UpdatesPurgeTheCache(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
testutil.RunStep(t, "first resolve", func(t *testing.T) {
|
testutil.RunStep(t, "first resolve", func(t *testing.T) {
|
||||||
authz, err := srv.ACLResolver.ResolveToken(token)
|
authz, err := srv.ACLResolver.ResolveTokenSecret(token)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Allow, authz.KeyRead("foo", nil))
|
require.Equal(t, acl.Allow, authz.KeyRead("foo", nil))
|
||||||
|
@ -2311,7 +2311,7 @@ func TestACLResolver_ResolveToken_UpdatesPurgeTheCache(t *testing.T) {
|
||||||
err := msgpackrpc.CallWithCodec(codec, "ACL.PolicySet", &reqPolicy, &structs.ACLPolicy{})
|
err := msgpackrpc.CallWithCodec(codec, "ACL.PolicySet", &reqPolicy, &structs.ACLPolicy{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := srv.ACLResolver.ResolveToken(token)
|
authz, err := srv.ACLResolver.ResolveTokenSecret(token)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, authz)
|
require.NotNil(t, authz)
|
||||||
require.Equal(t, acl.Deny, authz.KeyRead("foo", nil))
|
require.Equal(t, acl.Deny, authz.KeyRead("foo", nil))
|
||||||
|
@ -2327,7 +2327,7 @@ func TestACLResolver_ResolveToken_UpdatesPurgeTheCache(t *testing.T) {
|
||||||
err := msgpackrpc.CallWithCodec(codec, "ACL.TokenDelete", &req, &resp)
|
err := msgpackrpc.CallWithCodec(codec, "ACL.TokenDelete", &req, &resp)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, err = srv.ACLResolver.ResolveToken(token)
|
_, err = srv.ACLResolver.ResolveTokenSecret(token)
|
||||||
require.True(t, acl.IsErrNotFound(err), "Error %v is not acl.ErrNotFound", err)
|
require.True(t, acl.IsErrNotFound(err), "Error %v is not acl.ErrNotFound", err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ func (s *ConnectCA) ConfigurationGet(
|
||||||
}
|
}
|
||||||
|
|
||||||
// This action requires operator read access.
|
// This action requires operator read access.
|
||||||
authz, err := s.srv.ResolveToken(args.Token)
|
authz, err := s.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ func (s *ConnectCA) ConfigurationSet(
|
||||||
}
|
}
|
||||||
|
|
||||||
// This action requires operator write access.
|
// This action requires operator write access.
|
||||||
authz, err := s.srv.ResolveToken(args.Token)
|
authz, err := s.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ func (s *ConnectCA) Sign(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
authz, err := s.srv.ResolveToken(args.Token)
|
authz, err := s.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ func (s *ConnectCA) SignIntermediate(
|
||||||
}
|
}
|
||||||
|
|
||||||
// This action requires operator write access.
|
// This action requires operator write access.
|
||||||
authz, err := s.srv.ResolveToken(args.Token)
|
authz, err := s.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ func (c *FederationState) Apply(args *structs.FederationStateRequest, reply *boo
|
||||||
defer metrics.MeasureSince([]string{"federation_state", "apply"}, time.Now())
|
defer metrics.MeasureSince([]string{"federation_state", "apply"}, time.Now())
|
||||||
|
|
||||||
// Fetch the ACL token, if any.
|
// Fetch the ACL token, if any.
|
||||||
authz, err := c.srv.ResolveToken(args.Token)
|
authz, err := c.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ func (c *FederationState) Get(args *structs.FederationStateQuery, reply *structs
|
||||||
defer metrics.MeasureSince([]string{"federation_state", "get"}, time.Now())
|
defer metrics.MeasureSince([]string{"federation_state", "get"}, time.Now())
|
||||||
|
|
||||||
// Fetch the ACL token, if any.
|
// Fetch the ACL token, if any.
|
||||||
authz, err := c.srv.ResolveToken(args.Token)
|
authz, err := c.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ func (c *FederationState) List(args *structs.DCSpecificRequest, reply *structs.I
|
||||||
defer metrics.MeasureSince([]string{"federation_state", "list"}, time.Now())
|
defer metrics.MeasureSince([]string{"federation_state", "list"}, time.Now())
|
||||||
|
|
||||||
// Fetch the ACL token, if any.
|
// Fetch the ACL token, if any.
|
||||||
authz, err := c.srv.ResolveToken(args.Token)
|
authz, err := c.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -780,7 +780,7 @@ func (m *Internal) KeyringOperation(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check ACLs
|
// Check ACLs
|
||||||
authz, err := m.srv.ACLResolver.ResolveToken(args.Token)
|
authz, err := m.srv.ACLResolver.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ func (op *Operator) AutopilotGetConfiguration(args *structs.DCSpecificRequest, r
|
||||||
}
|
}
|
||||||
|
|
||||||
// This action requires operator read access.
|
// This action requires operator read access.
|
||||||
authz, err := op.srv.ACLResolver.ResolveToken(args.Token)
|
authz, err := op.srv.ACLResolver.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ func (op *Operator) AutopilotSetConfiguration(args *structs.AutopilotSetConfigRe
|
||||||
}
|
}
|
||||||
|
|
||||||
// This action requires operator write access.
|
// This action requires operator write access.
|
||||||
authz, err := op.srv.ACLResolver.ResolveToken(args.Token)
|
authz, err := op.srv.ACLResolver.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ func (op *Operator) ServerHealth(args *structs.DCSpecificRequest, reply *structs
|
||||||
}
|
}
|
||||||
|
|
||||||
// This action requires operator read access.
|
// This action requires operator read access.
|
||||||
authz, err := op.srv.ACLResolver.ResolveToken(args.Token)
|
authz, err := op.srv.ACLResolver.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ func (op *Operator) AutopilotState(args *structs.DCSpecificRequest, reply *autop
|
||||||
}
|
}
|
||||||
|
|
||||||
// This action requires operator read access.
|
// This action requires operator read access.
|
||||||
authz, err := op.srv.ACLResolver.ResolveToken(args.Token)
|
authz, err := op.srv.ACLResolver.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package consul
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/hashicorp/raft"
|
"github.com/hashicorp/raft"
|
||||||
|
@ -19,7 +18,7 @@ func (op *Operator) RaftGetConfiguration(args *structs.DCSpecificRequest, reply
|
||||||
}
|
}
|
||||||
|
|
||||||
// This action requires operator read access.
|
// This action requires operator read access.
|
||||||
authz, err := op.srv.ResolveToken(args.Token)
|
authz, err := op.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -81,7 +80,7 @@ func (op *Operator) RaftRemovePeerByAddress(args *structs.RaftRemovePeerRequest,
|
||||||
|
|
||||||
// This is a super dangerous operation that requires operator write
|
// This is a super dangerous operation that requires operator write
|
||||||
// access.
|
// access.
|
||||||
authz, err := op.srv.ACLResolver.ResolveToken(args.Token)
|
authz, err := op.srv.ACLResolver.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -134,7 +133,7 @@ func (op *Operator) RaftRemovePeerByID(args *structs.RaftRemovePeerRequest, repl
|
||||||
|
|
||||||
// This is a super dangerous operation that requires operator write
|
// This is a super dangerous operation that requires operator write
|
||||||
// access.
|
// access.
|
||||||
authz, err := op.srv.ACLResolver.ResolveToken(args.Token)
|
authz, err := op.srv.ACLResolver.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ func (p *PreparedQuery) Apply(args *structs.PreparedQueryRequest, reply *string)
|
||||||
*reply = args.Query.ID
|
*reply = args.Query.ID
|
||||||
|
|
||||||
// Get the ACL token for the request for the checks below.
|
// Get the ACL token for the request for the checks below.
|
||||||
authz, err := p.srv.ResolveToken(args.Token)
|
authz, err := p.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ func (s *Server) dispatchSnapshotRequest(args *structs.SnapshotRequest, in io.Re
|
||||||
// Verify token is allowed to operate on snapshots. There's only a
|
// Verify token is allowed to operate on snapshots. There's only a
|
||||||
// single ACL sense here (not read and write) since reading gets you
|
// single ACL sense here (not read and write) since reading gets you
|
||||||
// all the ACLs and you could escalate from there.
|
// all the ACLs and you could escalate from there.
|
||||||
if authz, err := s.ResolveToken(args.Token); err != nil {
|
if authz, err := s.ResolveTokenSecret(args.Token); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if err := authz.ToAllowAuthorizer().SnapshotAllowed(nil); err != nil {
|
} else if err := authz.ToAllowAuthorizer().SnapshotAllowed(nil); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -765,8 +765,8 @@ func (s *Store) ACLTokenBatchDelete(idx uint64, tokenIDs []string) error {
|
||||||
tx := s.db.WriteTxn(idx)
|
tx := s.db.WriteTxn(idx)
|
||||||
defer tx.Abort()
|
defer tx.Abort()
|
||||||
|
|
||||||
for _, tokenID := range tokenIDs {
|
for _, accessorID := range tokenIDs {
|
||||||
if err := aclTokenDeleteTxn(tx, idx, tokenID, indexAccessor, nil); err != nil {
|
if err := aclTokenDeleteTxn(tx, idx, accessorID, indexAccessor, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ func (t *Txn) Apply(args *structs.TxnRequest, reply *structs.TxnResponse) error
|
||||||
defer metrics.MeasureSince([]string{"txn", "apply"}, time.Now())
|
defer metrics.MeasureSince([]string{"txn", "apply"}, time.Now())
|
||||||
|
|
||||||
// Run the pre-checks before we send the transaction into Raft.
|
// Run the pre-checks before we send the transaction into Raft.
|
||||||
authz, err := t.srv.ResolveToken(args.Token)
|
authz, err := t.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ func (t *Txn) Read(args *structs.TxnReadRequest, reply *structs.TxnReadResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the pre-checks before we perform the read.
|
// Run the pre-checks before we perform the read.
|
||||||
authz, err := t.srv.ResolveToken(args.Token)
|
authz, err := t.srv.ResolveTokenSecret(args.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1244,7 +1244,7 @@ func (r *ACLTokenSetRequest) RequestDatacenter() string {
|
||||||
|
|
||||||
// ACLTokenGetRequest is used for token read operations at the RPC layer
|
// ACLTokenGetRequest is used for token read operations at the RPC layer
|
||||||
type ACLTokenGetRequest struct {
|
type ACLTokenGetRequest struct {
|
||||||
TokenID string // id used for the token lookup
|
TokenID string // Accessor ID used for the token lookup
|
||||||
TokenIDType ACLTokenIDType // The Type of ID used to lookup the token
|
TokenIDType ACLTokenIDType // The Type of ID used to lookup the token
|
||||||
Expanded bool
|
Expanded bool
|
||||||
Datacenter string // The datacenter to perform the request within
|
Datacenter string // The datacenter to perform the request within
|
||||||
|
@ -1258,7 +1258,7 @@ func (r *ACLTokenGetRequest) RequestDatacenter() string {
|
||||||
|
|
||||||
// ACLTokenDeleteRequest is used for token deletion operations at the RPC layer
|
// ACLTokenDeleteRequest is used for token deletion operations at the RPC layer
|
||||||
type ACLTokenDeleteRequest struct {
|
type ACLTokenDeleteRequest struct {
|
||||||
TokenID string // ID of the token to delete
|
TokenID string // Accessor ID of the token to delete
|
||||||
Datacenter string // The datacenter to perform the request within
|
Datacenter string // The datacenter to perform the request within
|
||||||
acl.EnterpriseMeta
|
acl.EnterpriseMeta
|
||||||
WriteRequest
|
WriteRequest
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
envoy_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
|
envoy_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/envoyextensions/xdscommon"
|
"github.com/hashicorp/consul/envoyextensions/xdscommon"
|
||||||
|
|
||||||
"github.com/armon/go-metrics"
|
"github.com/armon/go-metrics"
|
||||||
|
@ -102,11 +103,11 @@ type ProxyConfigSource interface {
|
||||||
// A full description of the XDS protocol can be found at
|
// A full description of the XDS protocol can be found at
|
||||||
// https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol
|
// https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol
|
||||||
type Server struct {
|
type Server struct {
|
||||||
NodeName string
|
NodeName string
|
||||||
Logger hclog.Logger
|
Logger hclog.Logger
|
||||||
CfgSrc ProxyConfigSource
|
CfgSrc ProxyConfigSource
|
||||||
ResolveToken ACLResolverFunc
|
ResolveTokenSecret ACLResolverFunc
|
||||||
CfgFetcher ConfigFetcher
|
CfgFetcher ConfigFetcher
|
||||||
|
|
||||||
// AuthCheckFrequency is how often we should re-check the credentials used
|
// AuthCheckFrequency is how often we should re-check the credentials used
|
||||||
// during a long-lived gRPC Stream after it has been initially established.
|
// during a long-lived gRPC Stream after it has been initially established.
|
||||||
|
@ -156,14 +157,14 @@ func NewServer(
|
||||||
nodeName string,
|
nodeName string,
|
||||||
logger hclog.Logger,
|
logger hclog.Logger,
|
||||||
cfgMgr ProxyConfigSource,
|
cfgMgr ProxyConfigSource,
|
||||||
resolveToken ACLResolverFunc,
|
resolveTokenSecret ACLResolverFunc,
|
||||||
cfgFetcher ConfigFetcher,
|
cfgFetcher ConfigFetcher,
|
||||||
) *Server {
|
) *Server {
|
||||||
return &Server{
|
return &Server{
|
||||||
NodeName: nodeName,
|
NodeName: nodeName,
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
CfgSrc: cfgMgr,
|
CfgSrc: cfgMgr,
|
||||||
ResolveToken: resolveToken,
|
ResolveTokenSecret: resolveTokenSecret,
|
||||||
CfgFetcher: cfgFetcher,
|
CfgFetcher: cfgFetcher,
|
||||||
AuthCheckFrequency: DefaultAuthCheckFrequency,
|
AuthCheckFrequency: DefaultAuthCheckFrequency,
|
||||||
activeStreams: &activeStreamCounters{},
|
activeStreams: &activeStreamCounters{},
|
||||||
|
@ -190,7 +191,7 @@ func (s *Server) authenticate(ctx context.Context) (acl.Authorizer, error) {
|
||||||
return nil, status.Errorf(codes.Internal, "error fetching options from context: %v", err)
|
return nil, status.Errorf(codes.Internal, "error fetching options from context: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
authz, err := s.ResolveToken(options.Token)
|
authz, err := s.ResolveTokenSecret(options.Token)
|
||||||
if acl.IsErrNotFound(err) {
|
if acl.IsErrNotFound(err) {
|
||||||
return nil, status.Errorf(codes.Unauthenticated, "unauthenticated: %v", err)
|
return nil, status.Errorf(codes.Unauthenticated, "unauthenticated: %v", err)
|
||||||
} else if acl.IsErrPermissionDenied(err) {
|
} else if acl.IsErrPermissionDenied(err) {
|
||||||
|
|
|
@ -159,7 +159,7 @@ type testServerScenario struct {
|
||||||
|
|
||||||
func newTestServerDeltaScenario(
|
func newTestServerDeltaScenario(
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
resolveToken ACLResolverFunc,
|
resolveTokenSecret ACLResolverFunc,
|
||||||
proxyID string,
|
proxyID string,
|
||||||
token string,
|
token string,
|
||||||
authCheckFrequency time.Duration,
|
authCheckFrequency time.Duration,
|
||||||
|
@ -185,7 +185,7 @@ func newTestServerDeltaScenario(
|
||||||
"node-123",
|
"node-123",
|
||||||
testutil.Logger(t),
|
testutil.Logger(t),
|
||||||
mgr,
|
mgr,
|
||||||
resolveToken,
|
resolveTokenSecret,
|
||||||
nil, /*cfgFetcher ConfigFetcher*/
|
nil, /*cfgFetcher ConfigFetcher*/
|
||||||
)
|
)
|
||||||
if authCheckFrequency > 0 {
|
if authCheckFrequency > 0 {
|
||||||
|
|
28
api/acl.go
28
api/acl.go
|
@ -746,14 +746,14 @@ func (a *ACL) TokenUpdate(token *ACLToken, q *WriteOptions) (*ACLToken, *WriteMe
|
||||||
|
|
||||||
// TokenClone will create a new token with the same policies and locality as the original
|
// TokenClone will create a new token with the same policies and locality as the original
|
||||||
// token but will have its own auto-generated AccessorID and SecretID as well having the
|
// token but will have its own auto-generated AccessorID and SecretID as well having the
|
||||||
// description passed to this function. The tokenID parameter must be a valid Accessor ID
|
// description passed to this function. The accessorID parameter must be a valid Accessor ID
|
||||||
// of an existing token.
|
// of an existing token.
|
||||||
func (a *ACL) TokenClone(tokenID string, description string, q *WriteOptions) (*ACLToken, *WriteMeta, error) {
|
func (a *ACL) TokenClone(accessorID string, description string, q *WriteOptions) (*ACLToken, *WriteMeta, error) {
|
||||||
if tokenID == "" {
|
if accessorID == "" {
|
||||||
return nil, nil, fmt.Errorf("Must specify a tokenID for Token Cloning")
|
return nil, nil, fmt.Errorf("Must specify a token AccessorID for Token Cloning")
|
||||||
}
|
}
|
||||||
|
|
||||||
r := a.c.newRequest("PUT", "/v1/acl/token/"+tokenID+"/clone")
|
r := a.c.newRequest("PUT", "/v1/acl/token/"+accessorID+"/clone")
|
||||||
r.setWriteOptions(q)
|
r.setWriteOptions(q)
|
||||||
r.obj = struct{ Description string }{description}
|
r.obj = struct{ Description string }{description}
|
||||||
rtt, resp, err := a.c.doRequest(r)
|
rtt, resp, err := a.c.doRequest(r)
|
||||||
|
@ -773,10 +773,10 @@ func (a *ACL) TokenClone(tokenID string, description string, q *WriteOptions) (*
|
||||||
return &out, wm, nil
|
return &out, wm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TokenDelete removes a single ACL token. The tokenID parameter must be a valid
|
// TokenDelete removes a single ACL token. The accessorID parameter must be a valid
|
||||||
// Accessor ID of an existing token.
|
// Accessor ID of an existing token.
|
||||||
func (a *ACL) TokenDelete(tokenID string, q *WriteOptions) (*WriteMeta, error) {
|
func (a *ACL) TokenDelete(accessorID string, q *WriteOptions) (*WriteMeta, error) {
|
||||||
r := a.c.newRequest("DELETE", "/v1/acl/token/"+tokenID)
|
r := a.c.newRequest("DELETE", "/v1/acl/token/"+accessorID)
|
||||||
r.setWriteOptions(q)
|
r.setWriteOptions(q)
|
||||||
rtt, resp, err := a.c.doRequest(r)
|
rtt, resp, err := a.c.doRequest(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -791,10 +791,10 @@ func (a *ACL) TokenDelete(tokenID string, q *WriteOptions) (*WriteMeta, error) {
|
||||||
return wm, nil
|
return wm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TokenRead retrieves the full token details. The tokenID parameter must be a valid
|
// TokenRead retrieves the full token details. The accessorID parameter must be a valid
|
||||||
// Accessor ID of an existing token.
|
// Accessor ID of an existing token.
|
||||||
func (a *ACL) TokenRead(tokenID string, q *QueryOptions) (*ACLToken, *QueryMeta, error) {
|
func (a *ACL) TokenRead(accessorID string, q *QueryOptions) (*ACLToken, *QueryMeta, error) {
|
||||||
r := a.c.newRequest("GET", "/v1/acl/token/"+tokenID)
|
r := a.c.newRequest("GET", "/v1/acl/token/"+accessorID)
|
||||||
r.setQueryOptions(q)
|
r.setQueryOptions(q)
|
||||||
rtt, resp, err := a.c.doRequest(r)
|
rtt, resp, err := a.c.doRequest(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -817,9 +817,9 @@ func (a *ACL) TokenRead(tokenID string, q *QueryOptions) (*ACLToken, *QueryMeta,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TokenReadExpanded retrieves the full token details, as well as the contents of any policies affecting the token.
|
// TokenReadExpanded retrieves the full token details, as well as the contents of any policies affecting the token.
|
||||||
// The tokenID parameter must be a valid Accessor ID of an existing token.
|
// The accessorID parameter must be a valid Accessor ID of an existing token.
|
||||||
func (a *ACL) TokenReadExpanded(tokenID string, q *QueryOptions) (*ACLTokenExpanded, *QueryMeta, error) {
|
func (a *ACL) TokenReadExpanded(accessorID string, q *QueryOptions) (*ACLTokenExpanded, *QueryMeta, error) {
|
||||||
r := a.c.newRequest("GET", "/v1/acl/token/"+tokenID)
|
r := a.c.newRequest("GET", "/v1/acl/token/"+accessorID)
|
||||||
r.setQueryOptions(q)
|
r.setQueryOptions(q)
|
||||||
r.params.Set("expanded", "true")
|
r.params.Set("expanded", "true")
|
||||||
rtt, resp, err := a.c.doRequest(r)
|
rtt, resp, err := a.c.doRequest(r)
|
||||||
|
|
|
@ -9,14 +9,14 @@ import (
|
||||||
"github.com/hashicorp/consul/api"
|
"github.com/hashicorp/consul/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetTokenIDFromPartial(client *api.Client, partialID string) (string, error) {
|
func GetTokenAccessorIDFromPartial(client *api.Client, partialAccessorID string) (string, error) {
|
||||||
if partialID == "anonymous" {
|
if partialAccessorID == "anonymous" {
|
||||||
return acl.AnonymousTokenID, nil
|
return acl.AnonymousTokenID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// the full UUID string was given
|
// the full UUID string was given
|
||||||
if len(partialID) == 36 {
|
if len(partialAccessorID) == 36 {
|
||||||
return partialID, nil
|
return partialAccessorID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens, _, err := client.ACL().TokenList(nil)
|
tokens, _, err := client.ACL().TokenList(nil)
|
||||||
|
@ -24,21 +24,21 @@ func GetTokenIDFromPartial(client *api.Client, partialID string) (string, error)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenID := ""
|
tokenAccessorID := ""
|
||||||
for _, token := range tokens {
|
for _, token := range tokens {
|
||||||
if strings.HasPrefix(token.AccessorID, partialID) {
|
if strings.HasPrefix(token.AccessorID, partialAccessorID) {
|
||||||
if tokenID != "" {
|
if tokenAccessorID != "" {
|
||||||
return "", fmt.Errorf("Partial token ID is not unique")
|
return "", fmt.Errorf("Partial token ID is not unique")
|
||||||
}
|
}
|
||||||
tokenID = token.AccessorID
|
tokenAccessorID = token.AccessorID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if tokenID == "" {
|
if tokenAccessorID == "" {
|
||||||
return "", fmt.Errorf("No such token ID with prefix: %s", partialID)
|
return "", fmt.Errorf("No such token ID with prefix: %s", partialAccessorID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return tokenID, nil
|
return tokenAccessorID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPolicyIDFromPartial(client *api.Client, partialID string) (string, error) {
|
func GetPolicyIDFromPartial(client *api.Client, partialID string) (string, error) {
|
||||||
|
|
|
@ -24,14 +24,16 @@ type cmd struct {
|
||||||
http *flags.HTTPFlags
|
http *flags.HTTPFlags
|
||||||
help string
|
help string
|
||||||
|
|
||||||
tokenID string
|
tokenAccessorID string
|
||||||
description string
|
description string
|
||||||
format string
|
format string
|
||||||
|
|
||||||
|
tokenID string // DEPRECATED
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cmd) init() {
|
func (c *cmd) init() {
|
||||||
c.flags = flag.NewFlagSet("", flag.ContinueOnError)
|
c.flags = flag.NewFlagSet("", flag.ContinueOnError)
|
||||||
c.flags.StringVar(&c.tokenID, "id", "", "The Accessor ID of the token to clone. "+
|
c.flags.StringVar(&c.tokenAccessorID, "accessor-id", "", "The Accessor ID of the token to clone. "+
|
||||||
"It may be specified as a unique ID prefix but will error if the prefix "+
|
"It may be specified as a unique ID prefix but will error if the prefix "+
|
||||||
"matches multiple token Accessor IDs. The special value of 'anonymous' may "+
|
"matches multiple token Accessor IDs. The special value of 'anonymous' may "+
|
||||||
"be provided instead of the anonymous tokens accessor ID")
|
"be provided instead of the anonymous tokens accessor ID")
|
||||||
|
@ -47,6 +49,10 @@ func (c *cmd) init() {
|
||||||
flags.Merge(c.flags, c.http.ServerFlags())
|
flags.Merge(c.flags, c.http.ServerFlags())
|
||||||
flags.Merge(c.flags, c.http.MultiTenancyFlags())
|
flags.Merge(c.flags, c.http.MultiTenancyFlags())
|
||||||
c.help = flags.Usage(help, c.flags)
|
c.help = flags.Usage(help, c.flags)
|
||||||
|
|
||||||
|
// Deprecations
|
||||||
|
c.flags.StringVar(&c.tokenID, "id", "",
|
||||||
|
"DEPRECATED. Use -accessor-id instead.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cmd) Run(args []string) int {
|
func (c *cmd) Run(args []string) int {
|
||||||
|
@ -54,9 +60,15 @@ func (c *cmd) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.tokenID == "" {
|
tokenAccessor := c.tokenAccessorID
|
||||||
c.UI.Error(fmt.Sprintf("Cannot update a token without specifying the -id parameter"))
|
if tokenAccessor == "" {
|
||||||
return 1
|
if c.tokenID == "" {
|
||||||
|
c.UI.Error("Cannot update a token without specifying the -accessor-id parameter")
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
tokenAccessor = c.tokenID
|
||||||
|
c.UI.Warn("The -id parameter is deprecated. Use the -accessor-id parameter instead.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := c.http.APIClient()
|
client, err := c.http.APIClient()
|
||||||
|
@ -65,13 +77,13 @@ func (c *cmd) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenID, err := acl.GetTokenIDFromPartial(client, c.tokenID)
|
tok, err := acl.GetTokenAccessorIDFromPartial(client, tokenAccessor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.UI.Error(fmt.Sprintf("Error determining token ID: %v", err))
|
c.UI.Error(fmt.Sprintf("Error determining token Accessor ID: %v", err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
t, _, err := client.ACL().TokenClone(tokenID, c.description, nil)
|
t, _, err := client.ACL().TokenClone(tok, c.description, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.UI.Error(fmt.Sprintf("Error cloning token: %v", err))
|
c.UI.Error(fmt.Sprintf("Error cloning token: %v", err))
|
||||||
return 1
|
return 1
|
||||||
|
@ -112,6 +124,6 @@ Usage: consul acl token clone [options]
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$ consul acl token clone -id abcd -description "replication"
|
$ consul acl token clone -accessor-id abcd -description "replication"
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
|
@ -100,7 +100,7 @@ func TestTokenCloneCommand_Pretty(t *testing.T) {
|
||||||
|
|
||||||
args := []string{
|
args := []string{
|
||||||
"-http-addr=" + a.HTTPAddr(),
|
"-http-addr=" + a.HTTPAddr(),
|
||||||
"-id=" + token.AccessorID,
|
"-accessor-id=" + token.AccessorID,
|
||||||
"-token=root",
|
"-token=root",
|
||||||
"-description=test cloned",
|
"-description=test cloned",
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ func TestTokenCloneCommand_Pretty(t *testing.T) {
|
||||||
|
|
||||||
args := []string{
|
args := []string{
|
||||||
"-http-addr=" + a.HTTPAddr(),
|
"-http-addr=" + a.HTTPAddr(),
|
||||||
"-id=" + token.AccessorID,
|
"-accessor-id=" + token.AccessorID,
|
||||||
"-token=root",
|
"-token=root",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ func TestTokenCloneCommand_JSON(t *testing.T) {
|
||||||
|
|
||||||
args := []string{
|
args := []string{
|
||||||
"-http-addr=" + a.HTTPAddr(),
|
"-http-addr=" + a.HTTPAddr(),
|
||||||
"-id=" + token.AccessorID,
|
"-accessor-id=" + token.AccessorID,
|
||||||
"-token=root",
|
"-token=root",
|
||||||
"-description=test cloned",
|
"-description=test cloned",
|
||||||
"-format=json",
|
"-format=json",
|
||||||
|
@ -230,7 +230,7 @@ func TestTokenCloneCommand_JSON(t *testing.T) {
|
||||||
|
|
||||||
args := []string{
|
args := []string{
|
||||||
"-http-addr=" + a.HTTPAddr(),
|
"-http-addr=" + a.HTTPAddr(),
|
||||||
"-id=" + token.AccessorID,
|
"-accessor-id=" + token.AccessorID,
|
||||||
"-token=root",
|
"-token=root",
|
||||||
"-format=json",
|
"-format=json",
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,17 +17,18 @@ func New(ui cli.Ui) *cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
type cmd struct {
|
type cmd struct {
|
||||||
UI cli.Ui
|
UI cli.Ui
|
||||||
flags *flag.FlagSet
|
flags *flag.FlagSet
|
||||||
http *flags.HTTPFlags
|
http *flags.HTTPFlags
|
||||||
help string
|
help string
|
||||||
|
tokenAccessorID string
|
||||||
|
|
||||||
tokenID string
|
tokenID string // DEPRECATED
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cmd) init() {
|
func (c *cmd) init() {
|
||||||
c.flags = flag.NewFlagSet("", flag.ContinueOnError)
|
c.flags = flag.NewFlagSet("", flag.ContinueOnError)
|
||||||
c.flags.StringVar(&c.tokenID, "id", "", "The Accessor ID of the token to delete. "+
|
c.flags.StringVar(&c.tokenAccessorID, "accessor-id", "", "The Accessor ID of the token to delete. "+
|
||||||
"It may be specified as a unique ID prefix but will error if the prefix "+
|
"It may be specified as a unique ID prefix but will error if the prefix "+
|
||||||
"matches multiple token Accessor IDs")
|
"matches multiple token Accessor IDs")
|
||||||
c.http = &flags.HTTPFlags{}
|
c.http = &flags.HTTPFlags{}
|
||||||
|
@ -36,6 +37,10 @@ func (c *cmd) init() {
|
||||||
flags.Merge(c.flags, c.http.ServerFlags())
|
flags.Merge(c.flags, c.http.ServerFlags())
|
||||||
flags.Merge(c.flags, c.http.MultiTenancyFlags())
|
flags.Merge(c.flags, c.http.MultiTenancyFlags())
|
||||||
c.help = flags.Usage(help, c.flags)
|
c.help = flags.Usage(help, c.flags)
|
||||||
|
|
||||||
|
// Deprecations
|
||||||
|
c.flags.StringVar(&c.tokenID, "id", "",
|
||||||
|
"DEPRECATED. Use -accessor-id instead.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cmd) Run(args []string) int {
|
func (c *cmd) Run(args []string) int {
|
||||||
|
@ -43,9 +48,15 @@ func (c *cmd) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.tokenID == "" {
|
tokenAccessor := c.tokenAccessorID
|
||||||
c.UI.Error(fmt.Sprintf("Must specify the -id parameter"))
|
if tokenAccessor == "" {
|
||||||
return 1
|
if c.tokenID == "" {
|
||||||
|
c.UI.Error("Must specify the -accessor-id parameter")
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
tokenAccessor = c.tokenID
|
||||||
|
c.UI.Warn("Use the -accessor-id parameter to specify token by Accessor ID.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := c.http.APIClient()
|
client, err := c.http.APIClient()
|
||||||
|
@ -54,18 +65,18 @@ func (c *cmd) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenID, err := acl.GetTokenIDFromPartial(client, c.tokenID)
|
tok, err := acl.GetTokenAccessorIDFromPartial(client, tokenAccessor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.UI.Error(fmt.Sprintf("Error determining token ID: %v", err))
|
c.UI.Error(fmt.Sprintf("Error determining token ID: %v", err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := client.ACL().TokenDelete(tokenID, nil); err != nil {
|
if _, err := client.ACL().TokenDelete(tok, nil); err != nil {
|
||||||
c.UI.Error(fmt.Sprintf("Error deleting token %q: %v", tokenID, err))
|
c.UI.Error(fmt.Sprintf("Error deleting token %q: %v", tok, err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
c.UI.Info(fmt.Sprintf("Token %q deleted successfully", tokenID))
|
c.UI.Info(fmt.Sprintf("Token %q deleted successfully", tok))
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,16 +91,16 @@ func (c *cmd) Help() string {
|
||||||
const (
|
const (
|
||||||
synopsis = "Delete an ACL token"
|
synopsis = "Delete an ACL token"
|
||||||
help = `
|
help = `
|
||||||
Usage: consul acl token delete [options] -id TOKEN
|
Usage: consul acl token delete [options] -accessor-id TOKEN
|
||||||
|
|
||||||
Deletes an ACL token by providing either the ID or a unique ID prefix.
|
Deletes an ACL token by providing either the ID or a unique ID prefix.
|
||||||
|
|
||||||
Delete by prefix:
|
Delete by prefix:
|
||||||
|
|
||||||
$ consul acl token delete -id b6b85
|
$ consul acl token delete -accessor-id b6b85
|
||||||
|
|
||||||
Delete by full ID:
|
Delete by full ID:
|
||||||
|
|
||||||
$ consul acl token delete -id b6b856da-5193-4e78-845a-7d61ca8371ba
|
$ consul acl token delete -accessor-id b6b856da-5193-4e78-845a-7d61ca8371ba
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,11 +5,12 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mitchellh/cli"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/agent"
|
"github.com/hashicorp/consul/agent"
|
||||||
"github.com/hashicorp/consul/api"
|
"github.com/hashicorp/consul/api"
|
||||||
"github.com/hashicorp/consul/testrpc"
|
"github.com/hashicorp/consul/testrpc"
|
||||||
"github.com/mitchellh/cli"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTokenDeleteCommand_noTabs(t *testing.T) {
|
func TestTokenDeleteCommand_noTabs(t *testing.T) {
|
||||||
|
@ -54,7 +55,7 @@ func TestTokenDeleteCommand(t *testing.T) {
|
||||||
args := []string{
|
args := []string{
|
||||||
"-http-addr=" + a.HTTPAddr(),
|
"-http-addr=" + a.HTTPAddr(),
|
||||||
"-token=root",
|
"-token=root",
|
||||||
"-id=" + token.AccessorID,
|
"-accessor-id=" + token.AccessorID,
|
||||||
}
|
}
|
||||||
|
|
||||||
code := cmd.Run(args)
|
code := cmd.Run(args)
|
||||||
|
|
|
@ -25,11 +25,13 @@ type cmd struct {
|
||||||
http *flags.HTTPFlags
|
http *flags.HTTPFlags
|
||||||
help string
|
help string
|
||||||
|
|
||||||
tokenID string
|
tokenAccessorID string
|
||||||
self bool
|
self bool
|
||||||
showMeta bool
|
showMeta bool
|
||||||
format string
|
format string
|
||||||
expanded bool
|
expanded bool
|
||||||
|
|
||||||
|
tokenID string // DEPRECATED
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cmd) init() {
|
func (c *cmd) init() {
|
||||||
|
@ -37,10 +39,10 @@ func (c *cmd) init() {
|
||||||
c.flags.BoolVar(&c.showMeta, "meta", false, "Indicates that token metadata such "+
|
c.flags.BoolVar(&c.showMeta, "meta", false, "Indicates that token metadata such "+
|
||||||
"as the content hash and Raft indices should be shown for each entry")
|
"as the content hash and Raft indices should be shown for each entry")
|
||||||
c.flags.BoolVar(&c.self, "self", false, "Indicates that the current HTTP token "+
|
c.flags.BoolVar(&c.self, "self", false, "Indicates that the current HTTP token "+
|
||||||
"should be read by secret ID instead of expecting a -id option")
|
"should be read by secret ID instead of expecting a -accessor-id option")
|
||||||
c.flags.BoolVar(&c.expanded, "expanded", false, "Indicates that the contents of the "+
|
c.flags.BoolVar(&c.expanded, "expanded", false, "Indicates that the contents of the "+
|
||||||
" policies and roles affecting the token should also be shown.")
|
" policies and roles affecting the token should also be shown.")
|
||||||
c.flags.StringVar(&c.tokenID, "id", "", "The Accessor ID of the token to read. "+
|
c.flags.StringVar(&c.tokenAccessorID, "accessor-id", "", "The Accessor ID of the token to read. "+
|
||||||
"It may be specified as a unique ID prefix but will error if the prefix "+
|
"It may be specified as a unique ID prefix but will error if the prefix "+
|
||||||
"matches multiple token Accessor IDs")
|
"matches multiple token Accessor IDs")
|
||||||
c.flags.StringVar(
|
c.flags.StringVar(
|
||||||
|
@ -54,6 +56,10 @@ func (c *cmd) init() {
|
||||||
flags.Merge(c.flags, c.http.ServerFlags())
|
flags.Merge(c.flags, c.http.ServerFlags())
|
||||||
flags.Merge(c.flags, c.http.MultiTenancyFlags())
|
flags.Merge(c.flags, c.http.MultiTenancyFlags())
|
||||||
c.help = flags.Usage(help, c.flags)
|
c.help = flags.Usage(help, c.flags)
|
||||||
|
|
||||||
|
// Deprecations
|
||||||
|
c.flags.StringVar(&c.tokenID, "id", "",
|
||||||
|
"DEPRECATED. Use -accessor-id instead.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cmd) Run(args []string) int {
|
func (c *cmd) Run(args []string) int {
|
||||||
|
@ -61,9 +67,15 @@ func (c *cmd) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.tokenID == "" && !c.self {
|
tokenAccessor := c.tokenAccessorID
|
||||||
c.UI.Error(fmt.Sprintf("Must specify the -id parameter"))
|
if tokenAccessor == "" {
|
||||||
return 1
|
if c.tokenID == "" {
|
||||||
|
c.UI.Error("Must specify the -accessor-id parameter")
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
tokenAccessor = c.tokenID
|
||||||
|
c.UI.Warn("Use the -accessor-id parameter to specify token by Accessor ID")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := c.http.APIClient()
|
client, err := c.http.APIClient()
|
||||||
|
@ -75,27 +87,27 @@ func (c *cmd) Run(args []string) int {
|
||||||
var t *api.ACLToken
|
var t *api.ACLToken
|
||||||
var expanded *api.ACLTokenExpanded
|
var expanded *api.ACLTokenExpanded
|
||||||
if !c.self {
|
if !c.self {
|
||||||
tokenID, err := acl.GetTokenIDFromPartial(client, c.tokenID)
|
tok, err := acl.GetTokenAccessorIDFromPartial(client, tokenAccessor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.UI.Error(fmt.Sprintf("Error determining token ID: %v", err))
|
c.UI.Error(fmt.Sprintf("Error determining token ID: %v", err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.expanded {
|
if !c.expanded {
|
||||||
t, _, err = client.ACL().TokenRead(tokenID, nil)
|
t, _, err = client.ACL().TokenRead(tok, nil)
|
||||||
} else {
|
} else {
|
||||||
expanded, _, err = client.ACL().TokenReadExpanded(tokenID, nil)
|
expanded, _, err = client.ACL().TokenReadExpanded(tok, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.UI.Error(fmt.Sprintf("Error reading token %q: %v", tokenID, err))
|
c.UI.Error(fmt.Sprintf("Error reading token %q: %v", tok, err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: consider updating this CLI command and underlying HTTP API endpoint
|
// TODO: consider updating this CLI command and underlying HTTP API endpoint
|
||||||
// to support expanded read of a "self" token, which is a much better user workflow.
|
// to support expanded read of a "self" token, which is a much better user workflow.
|
||||||
if c.expanded {
|
if c.expanded {
|
||||||
c.UI.Error("Cannot use both -expanded and -self. Instead, use -expanded and -id=<accessor id>.")
|
c.UI.Error("Cannot use both -expanded and -self. Instead, use -expanded and -accessor-id=<accessor id>.")
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,17 +151,17 @@ func (c *cmd) Help() string {
|
||||||
const (
|
const (
|
||||||
synopsis = "Read an ACL token"
|
synopsis = "Read an ACL token"
|
||||||
help = `
|
help = `
|
||||||
Usage: consul acl token read [options] -id TOKENID
|
Usage: consul acl token read [options] -accessor-id TOKENID
|
||||||
|
|
||||||
This command will retrieve and print out the details of
|
This command will retrieve and print out the details of
|
||||||
a single token.
|
a single token.
|
||||||
|
|
||||||
Using a partial ID:
|
Using a partial ID:
|
||||||
|
|
||||||
$ consul acl token read -id 4be56c77-82
|
$ consul acl token read -accessor-id 4be56c77-82
|
||||||
|
|
||||||
Using the full ID:
|
Using the full ID:
|
||||||
|
|
||||||
$ consul acl token read -id 4be56c77-8244-4c7d-b08c-667b8c71baed
|
$ consul acl token read -accessor-id 4be56c77-8244-4c7d-b08c-667b8c71baed
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,12 +6,13 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/agent"
|
|
||||||
"github.com/hashicorp/consul/api"
|
|
||||||
"github.com/hashicorp/consul/testrpc"
|
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/agent"
|
||||||
|
"github.com/hashicorp/consul/api"
|
||||||
|
"github.com/hashicorp/consul/testrpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTokenReadCommand_noTabs(t *testing.T) {
|
func TestTokenReadCommand_noTabs(t *testing.T) {
|
||||||
|
@ -56,7 +57,7 @@ func TestTokenReadCommand_Pretty(t *testing.T) {
|
||||||
args := []string{
|
args := []string{
|
||||||
"-http-addr=" + a.HTTPAddr(),
|
"-http-addr=" + a.HTTPAddr(),
|
||||||
"-token=root",
|
"-token=root",
|
||||||
"-id=" + token.AccessorID,
|
"-accessor-id=" + token.AccessorID,
|
||||||
}
|
}
|
||||||
|
|
||||||
code := cmd.Run(args)
|
code := cmd.Run(args)
|
||||||
|
@ -103,7 +104,7 @@ func TestTokenReadCommand_JSON(t *testing.T) {
|
||||||
args := []string{
|
args := []string{
|
||||||
"-http-addr=" + a.HTTPAddr(),
|
"-http-addr=" + a.HTTPAddr(),
|
||||||
"-token=root",
|
"-token=root",
|
||||||
"-id=" + token.AccessorID,
|
"-accessor-id=" + token.AccessorID,
|
||||||
"-format=json",
|
"-format=json",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package token
|
package token
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/consul/command/flags"
|
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/command/flags"
|
||||||
)
|
)
|
||||||
|
|
||||||
func New() *cmd {
|
func New() *cmd {
|
||||||
|
@ -42,15 +43,15 @@ Usage: consul acl token <subcommand> [options] [args]
|
||||||
|
|
||||||
Update a token:
|
Update a token:
|
||||||
|
|
||||||
$ consul acl token update -id 986193 -description "WonderToken"
|
$ consul acl token update -accessor-id 986193 -description "WonderToken"
|
||||||
|
|
||||||
Read a token with an accessor ID:
|
Read a token with an accessor ID:
|
||||||
|
|
||||||
$ consul acl token read -id 986193
|
$ consul acl token read -accessor-id 986193
|
||||||
|
|
||||||
Delete a token
|
Delete a token
|
||||||
|
|
||||||
$ consul acl token delete -id 986193
|
$ consul acl token delete -accessor-id 986193
|
||||||
|
|
||||||
For more examples, ask for subcommand help or view the documentation.
|
For more examples, ask for subcommand help or view the documentation.
|
||||||
`
|
`
|
||||||
|
|
|
@ -25,7 +25,7 @@ type cmd struct {
|
||||||
http *flags.HTTPFlags
|
http *flags.HTTPFlags
|
||||||
help string
|
help string
|
||||||
|
|
||||||
tokenID string
|
tokenAccessorID string
|
||||||
policyIDs []string
|
policyIDs []string
|
||||||
policyNames []string
|
policyNames []string
|
||||||
roleIDs []string
|
roleIDs []string
|
||||||
|
@ -39,6 +39,8 @@ type cmd struct {
|
||||||
mergeNodeIdents bool
|
mergeNodeIdents bool
|
||||||
showMeta bool
|
showMeta bool
|
||||||
format string
|
format string
|
||||||
|
|
||||||
|
tokenID string // DEPRECATED
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cmd) init() {
|
func (c *cmd) init() {
|
||||||
|
@ -53,7 +55,7 @@ func (c *cmd) init() {
|
||||||
"with the existing service identities")
|
"with the existing service identities")
|
||||||
c.flags.BoolVar(&c.mergeNodeIdents, "merge-node-identities", false, "Merge the new node identities "+
|
c.flags.BoolVar(&c.mergeNodeIdents, "merge-node-identities", false, "Merge the new node identities "+
|
||||||
"with the existing node identities")
|
"with the existing node identities")
|
||||||
c.flags.StringVar(&c.tokenID, "id", "", "The Accessor ID of the token to update. "+
|
c.flags.StringVar(&c.tokenAccessorID, "accessor-id", "", "The Accessor ID of the token to update. "+
|
||||||
"It may be specified as a unique ID prefix but will error if the prefix "+
|
"It may be specified as a unique ID prefix but will error if the prefix "+
|
||||||
"matches multiple token Accessor IDs")
|
"matches multiple token Accessor IDs")
|
||||||
c.flags.StringVar(&c.description, "description", "", "A description of the token")
|
c.flags.StringVar(&c.description, "description", "", "A description of the token")
|
||||||
|
@ -83,6 +85,10 @@ func (c *cmd) init() {
|
||||||
flags.Merge(c.flags, c.http.ServerFlags())
|
flags.Merge(c.flags, c.http.ServerFlags())
|
||||||
flags.Merge(c.flags, c.http.MultiTenancyFlags())
|
flags.Merge(c.flags, c.http.MultiTenancyFlags())
|
||||||
c.help = flags.Usage(help, c.flags)
|
c.help = flags.Usage(help, c.flags)
|
||||||
|
|
||||||
|
// Deprecations
|
||||||
|
c.flags.StringVar(&c.tokenID, "id", "",
|
||||||
|
"DEPRECATED. Use -accessor-id instead.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cmd) Run(args []string) int {
|
func (c *cmd) Run(args []string) int {
|
||||||
|
@ -90,9 +96,15 @@ func (c *cmd) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.tokenID == "" {
|
tokenAccessor := c.tokenAccessorID
|
||||||
c.UI.Error(fmt.Sprintf("Cannot update a token without specifying the -id parameter"))
|
if tokenAccessor == "" {
|
||||||
return 1
|
if c.tokenID == "" {
|
||||||
|
c.UI.Error("Cannot update a token without specifying the -accessor-id parameter")
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
tokenAccessor = c.tokenID
|
||||||
|
c.UI.Warn("Use the -accessor-id parameter to specify token by Accessor ID")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := c.http.APIClient()
|
client, err := c.http.APIClient()
|
||||||
|
@ -101,13 +113,13 @@ func (c *cmd) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenID, err := acl.GetTokenIDFromPartial(client, c.tokenID)
|
tok, err := acl.GetTokenAccessorIDFromPartial(client, tokenAccessor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.UI.Error(fmt.Sprintf("Error determining token ID: %v", err))
|
c.UI.Error(fmt.Sprintf("Error determining token ID: %v", err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
t, _, err := client.ACL().TokenRead(tokenID, nil)
|
t, _, err := client.ACL().TokenRead(tok, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.UI.Error(fmt.Sprintf("Error when retrieving current token: %v", err))
|
c.UI.Error(fmt.Sprintf("Error when retrieving current token: %v", err))
|
||||||
return 1
|
return 1
|
||||||
|
@ -285,7 +297,7 @@ func (c *cmd) Run(args []string) int {
|
||||||
|
|
||||||
t, _, err = client.ACL().TokenUpdate(t, nil)
|
t, _, err = client.ACL().TokenUpdate(t, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.UI.Error(fmt.Sprintf("Failed to update token %s: %v", tokenID, err))
|
c.UI.Error(fmt.Sprintf("Failed to update token %s: %v", tok, err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,11 +336,11 @@ Usage: consul acl token update [options]
|
||||||
|
|
||||||
Update a token description and take the policies from the existing token:
|
Update a token description and take the policies from the existing token:
|
||||||
|
|
||||||
$ consul acl token update -id abcd -description "replication" -merge-policies
|
$ consul acl token update -accessor-id abcd -description "replication" -merge-policies
|
||||||
|
|
||||||
Update all editable fields of the token:
|
Update all editable fields of the token:
|
||||||
|
|
||||||
$ consul acl token update -id abcd \
|
$ consul acl token update -accessor-id abcd \
|
||||||
-description "replication" \
|
-description "replication" \
|
||||||
-policy-name "token-replication" \
|
-policy-name "token-replication" \
|
||||||
-role-name "db-updater"
|
-role-name "db-updater"
|
||||||
|
|
|
@ -74,7 +74,7 @@ func TestTokenUpdateCommand(t *testing.T) {
|
||||||
t.Run("node-identity", func(t *testing.T) {
|
t.Run("node-identity", func(t *testing.T) {
|
||||||
token := run(t, []string{
|
token := run(t, []string{
|
||||||
"-http-addr=" + a.HTTPAddr(),
|
"-http-addr=" + a.HTTPAddr(),
|
||||||
"-id=" + token.AccessorID,
|
"-accessor-id=" + token.AccessorID,
|
||||||
"-token=root",
|
"-token=root",
|
||||||
"-node-identity=foo:bar",
|
"-node-identity=foo:bar",
|
||||||
"-description=test token",
|
"-description=test token",
|
||||||
|
@ -88,7 +88,7 @@ func TestTokenUpdateCommand(t *testing.T) {
|
||||||
t.Run("node-identity-merge", func(t *testing.T) {
|
t.Run("node-identity-merge", func(t *testing.T) {
|
||||||
token := run(t, []string{
|
token := run(t, []string{
|
||||||
"-http-addr=" + a.HTTPAddr(),
|
"-http-addr=" + a.HTTPAddr(),
|
||||||
"-id=" + token.AccessorID,
|
"-accessor-id=" + token.AccessorID,
|
||||||
"-token=root",
|
"-token=root",
|
||||||
"-node-identity=bar:baz",
|
"-node-identity=bar:baz",
|
||||||
"-description=test token",
|
"-description=test token",
|
||||||
|
@ -113,7 +113,7 @@ func TestTokenUpdateCommand(t *testing.T) {
|
||||||
t.Run("policy-name", func(t *testing.T) {
|
t.Run("policy-name", func(t *testing.T) {
|
||||||
token := run(t, []string{
|
token := run(t, []string{
|
||||||
"-http-addr=" + a.HTTPAddr(),
|
"-http-addr=" + a.HTTPAddr(),
|
||||||
"-id=" + token.AccessorID,
|
"-accessor-id=" + token.AccessorID,
|
||||||
"-token=root",
|
"-token=root",
|
||||||
"-policy-name=" + policy.Name,
|
"-policy-name=" + policy.Name,
|
||||||
"-description=test token",
|
"-description=test token",
|
||||||
|
@ -126,7 +126,7 @@ func TestTokenUpdateCommand(t *testing.T) {
|
||||||
t.Run("policy-id", func(t *testing.T) {
|
t.Run("policy-id", func(t *testing.T) {
|
||||||
token := run(t, []string{
|
token := run(t, []string{
|
||||||
"-http-addr=" + a.HTTPAddr(),
|
"-http-addr=" + a.HTTPAddr(),
|
||||||
"-id=" + token.AccessorID,
|
"-accessor-id=" + token.AccessorID,
|
||||||
"-token=root",
|
"-token=root",
|
||||||
"-policy-id=" + policy.ID,
|
"-policy-id=" + policy.ID,
|
||||||
"-description=test token",
|
"-description=test token",
|
||||||
|
@ -139,7 +139,7 @@ func TestTokenUpdateCommand(t *testing.T) {
|
||||||
t.Run("merge-description", func(t *testing.T) {
|
t.Run("merge-description", func(t *testing.T) {
|
||||||
token := run(t, []string{
|
token := run(t, []string{
|
||||||
"-http-addr=" + a.HTTPAddr(),
|
"-http-addr=" + a.HTTPAddr(),
|
||||||
"-id=" + token.AccessorID,
|
"-accessor-id=" + token.AccessorID,
|
||||||
"-token=root",
|
"-token=root",
|
||||||
"-policy-name=" + policy.Name,
|
"-policy-name=" + policy.Name,
|
||||||
})
|
})
|
||||||
|
@ -189,7 +189,7 @@ func TestTokenUpdateCommand_JSON(t *testing.T) {
|
||||||
cmd := New(ui)
|
cmd := New(ui)
|
||||||
args := []string{
|
args := []string{
|
||||||
"-http-addr=" + a.HTTPAddr(),
|
"-http-addr=" + a.HTTPAddr(),
|
||||||
"-id=" + token.AccessorID,
|
"-accessor-id=" + token.AccessorID,
|
||||||
"-token=root",
|
"-token=root",
|
||||||
"-policy-name=" + policy.Name,
|
"-policy-name=" + policy.Name,
|
||||||
"-description=test token",
|
"-description=test token",
|
||||||
|
|
|
@ -143,7 +143,6 @@ Refer to the [API](/consul/api-docs/acl/tokens) or [command line](/consul/comman
|
||||||
| `Local` | Indicates whether the token should be replicated globally or local to the datacenter. <br/> Set to `false` to replicate globally across all reachable datacenters. <br/>Setting to `true` configures the token to functional in the local datacenter only. | Boolean | `false` |
|
| `Local` | Indicates whether the token should be replicated globally or local to the datacenter. <br/> Set to `false` to replicate globally across all reachable datacenters. <br/>Setting to `true` configures the token to functional in the local datacenter only. | Boolean | `false` |
|
||||||
| `ServiceIdentities` | Specifies a list of service identities to apply to the token. See [Service Identities](/consul/docs/security/acl/acl-roles#service-identities) in the "Roles" topic for additional information. | Array | none |
|
| `ServiceIdentities` | Specifies a list of service identities to apply to the token. See [Service Identities](/consul/docs/security/acl/acl-roles#service-identities) in the "Roles" topic for additional information. | Array | none |
|
||||||
| `NodeIdentities` | Specifies a list of node identities to apply to the token. See [Node Identities](/consul/docs/security/acl/acl-roles#node-identities) in the "Roles" topic for additional information. | Array | none |
|
| `NodeIdentities` | Specifies a list of node identities to apply to the token. See [Node Identities](/consul/docs/security/acl/acl-roles#node-identities) in the "Roles" topic for additional information. | Array | none |
|
||||||
| `Legacy` | Indicates if the token was created using the the legacy ACL system. | Boolean | `false` |
|
|
||||||
| `Policies` | List of policies linked to the token, including the policy ID and name. | String | none |
|
| `Policies` | List of policies linked to the token, including the policy ID and name. | String | none |
|
||||||
| `Roles` | List of roles linked to the token, including the role ID and name. | String | none |
|
| `Roles` | List of roles linked to the token, including the role ID and name. | String | none |
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue