nomad: only activate one-time auth tokens with 1.1.0 (#10952)
Fix a panic in handling one-time auth tokens, used to support `nomad ui --authenticate`. If the nomad leader is a 1.1.x with some servers running as 1.0.x, the pre-1.1.0 servers risk crashing and the cluster may lose quorum. That can happen when `nomad authenticate -ui` command is issued, or when the leader scans for expired tokens every 10 minutes. Fixed #10943 .
This commit is contained in:
parent
a15d03556c
commit
ac3cf10849
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
core: Fixed a panic that may arise when upgrading pre-1.1.0 cluster to 1.1.x and may cause cluster outage
|
||||||
|
```
|
|
@ -851,6 +851,10 @@ func (a *ACL) UpsertOneTimeToken(args *structs.OneTimeTokenUpsertRequest, reply
|
||||||
defer metrics.MeasureSince(
|
defer metrics.MeasureSince(
|
||||||
[]string{"nomad", "acl", "upsert_one_time_token"}, time.Now())
|
[]string{"nomad", "acl", "upsert_one_time_token"}, time.Now())
|
||||||
|
|
||||||
|
if !ServersMeetMinimumVersion(a.srv.Members(), minOneTimeAuthenticationTokenVersion, false) {
|
||||||
|
return fmt.Errorf("All servers should be running version %v or later to use one-time authentication tokens", minAutopilotVersion)
|
||||||
|
}
|
||||||
|
|
||||||
// Snapshot the state
|
// Snapshot the state
|
||||||
state, err := a.srv.State().Snapshot()
|
state, err := a.srv.State().Snapshot()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -899,6 +903,10 @@ func (a *ACL) ExchangeOneTimeToken(args *structs.OneTimeTokenExchangeRequest, re
|
||||||
defer metrics.MeasureSince(
|
defer metrics.MeasureSince(
|
||||||
[]string{"nomad", "acl", "exchange_one_time_token"}, time.Now())
|
[]string{"nomad", "acl", "exchange_one_time_token"}, time.Now())
|
||||||
|
|
||||||
|
if !ServersMeetMinimumVersion(a.srv.Members(), minOneTimeAuthenticationTokenVersion, false) {
|
||||||
|
return fmt.Errorf("All servers should be running version %v or later to use one-time authentication tokens", minAutopilotVersion)
|
||||||
|
}
|
||||||
|
|
||||||
// Snapshot the state
|
// Snapshot the state
|
||||||
state, err := a.srv.State().Snapshot()
|
state, err := a.srv.State().Snapshot()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -952,6 +960,10 @@ func (a *ACL) ExpireOneTimeTokens(args *structs.OneTimeTokenExpireRequest, reply
|
||||||
defer metrics.MeasureSince(
|
defer metrics.MeasureSince(
|
||||||
[]string{"nomad", "acl", "expire_one_time_tokens"}, time.Now())
|
[]string{"nomad", "acl", "expire_one_time_tokens"}, time.Now())
|
||||||
|
|
||||||
|
if !ServersMeetMinimumVersion(a.srv.Members(), minOneTimeAuthenticationTokenVersion, false) {
|
||||||
|
return fmt.Errorf("All servers should be running version %v or later to use one-time authentication tokens", minAutopilotVersion)
|
||||||
|
}
|
||||||
|
|
||||||
// Check management level permissions
|
// Check management level permissions
|
||||||
if a.srv.config.ACLEnabled {
|
if a.srv.config.ACLEnabled {
|
||||||
if acl, err := a.srv.ResolveToken(args.AuthToken); err != nil {
|
if acl, err := a.srv.ResolveToken(args.AuthToken); err != nil {
|
||||||
|
|
|
@ -48,6 +48,8 @@ var minClusterIDVersion = version.Must(version.NewVersion("0.10.4"))
|
||||||
|
|
||||||
var minJobRegisterAtomicEvalVersion = version.Must(version.NewVersion("0.12.1"))
|
var minJobRegisterAtomicEvalVersion = version.Must(version.NewVersion("0.12.1"))
|
||||||
|
|
||||||
|
var minOneTimeAuthenticationTokenVersion = version.Must(version.NewVersion("1.1.0"))
|
||||||
|
|
||||||
// monitorLeadership is used to monitor if we acquire or lose our role
|
// monitorLeadership is used to monitor if we acquire or lose our role
|
||||||
// as the leader in the Raft cluster. There is some work the leader is
|
// as the leader in the Raft cluster. There is some work the leader is
|
||||||
// expected to do, so we must react to changes
|
// expected to do, so we must react to changes
|
||||||
|
@ -739,6 +741,10 @@ func (s *Server) schedulePeriodic(stopCh chan struct{}) {
|
||||||
s.evalBroker.Enqueue(s.coreJobEval(structs.CoreJobCSIVolumeClaimGC, index))
|
s.evalBroker.Enqueue(s.coreJobEval(structs.CoreJobCSIVolumeClaimGC, index))
|
||||||
}
|
}
|
||||||
case <-oneTimeTokenGC.C:
|
case <-oneTimeTokenGC.C:
|
||||||
|
if !ServersMeetMinimumVersion(s.Members(), minOneTimeAuthenticationTokenVersion, false) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if index, ok := getLatest(); ok {
|
if index, ok := getLatest(); ok {
|
||||||
s.evalBroker.Enqueue(s.coreJobEval(structs.CoreJobOneTimeTokenGC, index))
|
s.evalBroker.Enqueue(s.coreJobEval(structs.CoreJobOneTimeTokenGC, index))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue