From 2f8b1eb5eb8845001920e2b5b758b383a4bf0f44 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 4 Dec 2018 09:27:37 -0500 Subject: [PATCH] server/nomad: Lock Vault expiration tracking `currentExpiration` field is accessed in multiple goroutines: Stats and renewal, so needs locking. I don't anticipate high contention, so simple mutex suffices. --- nomad/vault.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/nomad/vault.go b/nomad/vault.go index f866a8d20b7..ebf4bced284 100644 --- a/nomad/vault.go +++ b/nomad/vault.go @@ -145,7 +145,7 @@ type VaultStats struct { // TokenTTL is the time-to-live duration for the current token TokenTTL time.Duration - // TokenExpiry Time is the recoreded expiry time of the current token + // TokenExpiry is the recorded expiry time of the current token TokenExpiry time.Time } @@ -216,7 +216,8 @@ type vaultClient struct { childTTL string // currentExpiration is the time the current token lease expires - currentExpiration time.Time + currentExpiration time.Time + currentExpirationLock sync.Mutex tomb *tomb.Tomb logger log.Logger @@ -488,7 +489,9 @@ func (v *vaultClient) renewalLoop() { case <-authRenewTimer.C: // Renew the token and determine the new expiration recoverable, err := v.renew() + v.currentExpirationLock.Lock() currentExpiration := v.currentExpiration + v.currentExpirationLock.Unlock() // Successfully renewed if err == nil { @@ -602,7 +605,7 @@ func (v *vaultClient) renew() (bool, error) { return true, fmt.Errorf("renewal successful but no lease duration returned") } - v.currentExpiration = time.Now().Add(time.Duration(auth.LeaseDuration) * time.Second) + v.extendExpiration(auth.LeaseDuration) v.logger.Debug("successfully renewed server token") return true, nil @@ -650,7 +653,7 @@ func (v *vaultClient) parseSelfToken() error { } data.Root = root v.tokenData = &data - v.currentExpiration = time.Now().Add(time.Duration(data.TTL) * time.Second) + v.extendExpiration(data.TTL) // The criteria that must be met for the token to be valid are as follows: // 1) If token is non-root or is but has a creation ttl @@ -1274,7 +1277,10 @@ func (v *vaultClient) stats() *VaultStats { stats.TrackedForRevoke = len(v.revoking) v.revLock.Unlock() + v.currentExpirationLock.Lock() stats.TokenExpiry = v.currentExpiration + v.currentExpirationLock.Unlock() + if !stats.TokenExpiry.IsZero() { stats.TokenTTL = time.Until(stats.TokenExpiry) } @@ -1296,3 +1302,10 @@ func (v *vaultClient) EmitStats(period time.Duration, stopCh chan struct{}) { } } } + +// extendExpiration sets the current auth token expiration record to ttLSeconds seconds from now +func (v *vaultClient) extendExpiration(ttlSeconds int) { + v.currentExpirationLock.Lock() + v.currentExpiration = time.Now().Add(time.Duration(ttlSeconds) * time.Second) + v.currentExpirationLock.Unlock() +}