First part of perf standby entity race fix (#6106)
This commit is contained in:
parent
1f57e3674a
commit
e781ea3ac4
|
@ -561,7 +561,7 @@ func forwardRequest(core *vault.Core, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// request is a helper to perform a request and properly exit in the
|
||||
// case of an error.
|
||||
func request(core *vault.Core, w http.ResponseWriter, rawReq *http.Request, r *logical.Request) (*logical.Response, bool) {
|
||||
func request(core *vault.Core, w http.ResponseWriter, rawReq *http.Request, r *logical.Request) (*logical.Response, bool, bool) {
|
||||
resp, err := core.HandleRequest(rawReq.Context(), r)
|
||||
if r.LastRemoteWAL() > 0 && !vault.WaitUntilWALShipped(rawReq.Context(), core, r.LastRemoteWAL()) {
|
||||
if resp == nil {
|
||||
|
@ -571,14 +571,17 @@ func request(core *vault.Core, w http.ResponseWriter, rawReq *http.Request, r *l
|
|||
}
|
||||
if errwrap.Contains(err, consts.ErrStandby.Error()) {
|
||||
respondStandby(core, w, rawReq.URL)
|
||||
return resp, false
|
||||
return resp, false, false
|
||||
}
|
||||
if err != nil && errwrap.Contains(err, logical.ErrPerfStandbyPleaseForward.Error()) {
|
||||
return nil, false, true
|
||||
}
|
||||
|
||||
if respondErrorCommon(w, r, resp, err) {
|
||||
return resp, false
|
||||
return resp, false, false
|
||||
}
|
||||
|
||||
return resp, true
|
||||
return resp, true, false
|
||||
}
|
||||
|
||||
// respondStandby is used to trigger a redirect in the case that this Vault is currently a hot standby
|
||||
|
|
|
@ -208,7 +208,11 @@ func handleLogicalInternal(core *vault.Core, injectDataIntoTopLevel bool) http.H
|
|||
// it. Vault core handles stripping this if we need to. This also
|
||||
// handles all error cases; if we hit respondLogical, the request is a
|
||||
// success.
|
||||
resp, ok := request(core, w, r, req)
|
||||
resp, ok, needsForward := request(core, w, r, req)
|
||||
if needsForward {
|
||||
forwardRequest(core, w, r)
|
||||
return
|
||||
}
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -24,6 +24,10 @@ var (
|
|||
// ErrUpstreamRateLimited is returned when Vault receives a rate limited
|
||||
// response from an upstream
|
||||
ErrUpstreamRateLimited = errors.New("upstream rate limited")
|
||||
|
||||
// ErrPerfStandbyForward is returned when Vault is in a state such that a
|
||||
// perf standby cannot satisfy a request
|
||||
ErrPerfStandbyPleaseForward = errors.New("please forward to the active node")
|
||||
)
|
||||
|
||||
type HTTPCodedError interface {
|
||||
|
|
|
@ -251,6 +251,9 @@ func (c *Core) checkToken(ctx context.Context, req *logical.Request, unauth bool
|
|||
return nil, te, logical.ErrPermissionDenied
|
||||
}
|
||||
if te != nil && te.EntityID != "" && entity == nil {
|
||||
if c.perfStandby {
|
||||
return nil, nil, logical.ErrPerfStandbyPleaseForward
|
||||
}
|
||||
c.logger.Warn("permission denied as the entity on the token is invalid")
|
||||
return nil, te, logical.ErrPermissionDenied
|
||||
}
|
||||
|
@ -529,7 +532,13 @@ func (c *Core) handleRequest(ctx context.Context, req *logical.Request) (retResp
|
|||
|
||||
// Validate the token
|
||||
auth, te, ctErr := c.checkToken(ctx, req, false)
|
||||
// We run this logic first because we want to decrement the use count even in the case of an error
|
||||
if ctErr == logical.ErrPerfStandbyPleaseForward {
|
||||
return nil, nil, ctErr
|
||||
}
|
||||
|
||||
// We run this logic first because we want to decrement the use count even
|
||||
// in the case of an error (assuming we can successfully look up; if we
|
||||
// need to forward, we exit before now)
|
||||
if te != nil && !isControlGroupRun(req) {
|
||||
// Attempt to use the token (decrement NumUses)
|
||||
var err error
|
||||
|
@ -854,6 +863,9 @@ func (c *Core) handleLoginRequest(ctx context.Context, req *logical.Request) (re
|
|||
// Do an unauth check. This will cause EGP policies to be checked
|
||||
var ctErr error
|
||||
auth, _, ctErr = c.checkToken(ctx, req, true)
|
||||
if ctErr == logical.ErrPerfStandbyPleaseForward {
|
||||
return nil, nil, ctErr
|
||||
}
|
||||
if ctErr != nil {
|
||||
// If it is an internal error we return that, otherwise we
|
||||
// return invalid request so that the status codes can be correct
|
||||
|
|
Loading…
Reference in New Issue