acl: only run startACLUpgrade once

Since legacy ACL tokens can no longer be created we only need to run this upgrade a single
time when leadership is estalbished.
This commit is contained in:
Daniel Nephin 2021-09-29 16:14:36 -04:00
parent f21097beda
commit 0c077d0527
4 changed files with 19 additions and 20 deletions

View File

@ -54,14 +54,6 @@ const (
// are not allowed to be displayed.
redactedToken = "<hidden>"
// aclUpgradeBatchSize controls how many tokens we look at during each round of upgrading. Individual raft logs
// will be further capped using the aclBatchUpsertSize. This limit just prevents us from creating a single slice
// with all tokens in it.
aclUpgradeBatchSize = 128
// aclUpgradeRateLimit is the number of batch upgrade requests per second allowed.
aclUpgradeRateLimit rate.Limit = 1.0
// aclTokenReapingRateLimit is the number of batch token reaping requests per second allowed.
aclTokenReapingRateLimit rate.Limit = 1.0

View File

@ -13,7 +13,6 @@ import (
"github.com/armon/go-metrics"
"github.com/armon/go-metrics/prometheus"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-memdb"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/go-version"
"github.com/hashicorp/raft"
@ -541,9 +540,19 @@ func (s *Server) initializeACLs(ctx context.Context) error {
return nil
}
// This function is only intended to be run as a managed go routine, it will block until
// the context passed in indicates that it should exit.
// legacyACLTokenUpgrade runs a single time to upgrade any tokens that may
// have been created immediately before the Consul upgrade, or any legacy tokens
// from a restored snapshot.
// TODO(ACL-Legacy-Compat): remove in phase 2
func (s *Server) legacyACLTokenUpgrade(ctx context.Context) error {
// aclUpgradeRateLimit is the number of batch upgrade requests per second allowed.
const aclUpgradeRateLimit rate.Limit = 1.0
// aclUpgradeBatchSize controls how many tokens we look at during each round of upgrading. Individual raft logs
// will be further capped using the aclBatchUpsertSize. This limit just prevents us from creating a single slice
// with all tokens in it.
const aclUpgradeBatchSize = 128
limiter := rate.NewLimiter(aclUpgradeRateLimit, int(aclUpgradeRateLimit))
for {
if err := limiter.Wait(ctx); err != nil {
@ -552,21 +561,15 @@ func (s *Server) legacyACLTokenUpgrade(ctx context.Context) error {
// actually run the upgrade here
state := s.fsm.State()
tokens, waitCh, err := state.ACLTokenListUpgradeable(aclUpgradeBatchSize)
tokens, _, err := state.ACLTokenListUpgradeable(aclUpgradeBatchSize)
if err != nil {
s.logger.Warn("encountered an error while searching for tokens without accessor ids", "error", err)
}
// No need to check expiration time here, as that only exists for v2 tokens.
if len(tokens) == 0 {
ws := memdb.NewWatchSet()
ws.Add(state.AbandonCh())
ws.Add(waitCh)
ws.Add(ctx.Done())
// wait for more tokens to need upgrading or the aclUpgradeCh to be closed
ws.Watch(nil)
continue
// No new legacy tokens can be created, so we can exit
return nil
}
var newTokens structs.ACLTokens
@ -615,6 +618,8 @@ func (s *Server) legacyACLTokenUpgrade(ctx context.Context) error {
}
}
// TODO(ACL-Legacy-Compat): remove in phase 2. Keeping it for now so that we
// can upgrade any tokens created immediately before the upgrade happens.
func (s *Server) startACLUpgrade(ctx context.Context) {
if s.config.PrimaryDatacenter != s.config.Datacenter {
// token upgrades should only run in the primary

View File

@ -728,6 +728,7 @@ func (s *Store) ACLTokenList(ws memdb.WatchSet, local, global bool, policy, role
return idx, result, nil
}
// TODO(ACL-Legacy-Compat): remove in phase 2
func (s *Store) ACLTokenListUpgradeable(max int) (structs.ACLTokens, <-chan struct{}, error) {
tx := s.db.Txn(false)
defer tx.Abort()

View File

@ -107,6 +107,7 @@ func tokensTableSchema() *memdb.TableSchema {
//DEPRECATED (ACL-Legacy-Compat) - This index is only needed while we support upgrading v1 to v2 acls
// This table indexes all the ACL tokens that do not have an AccessorID
// TODO(ACL-Legacy-Compat): remove in phase 2
"needs-upgrade": {
Name: "needs-upgrade",
AllowMissing: false,