agent/token: rename `agent_master` to `agent_recovery` (internally) (#11744)
This commit is contained in:
parent
cfabdbba21
commit
0230ebb4ef
|
@ -0,0 +1,3 @@
|
|||
```release-note:note
|
||||
Renamed the `agent_master` field to `agent_recovery` in the `acl-tokens.json` file in which tokens are persisted on-disk (when `acl.enable_token_persistence` is enabled)
|
||||
```
|
|
@ -1510,7 +1510,7 @@ func (s *HTTPHandlers) AgentToken(resp http.ResponseWriter, req *http.Request) (
|
|||
}
|
||||
|
||||
case "acl_agent_master_token", "agent_master", "agent_recovery":
|
||||
s.agent.tokens.UpdateAgentMasterToken(args.Token, token_store.TokenSourceAPI)
|
||||
s.agent.tokens.UpdateAgentRecoveryToken(args.Token, token_store.TokenSourceAPI)
|
||||
|
||||
case "acl_replication_token", "replication":
|
||||
s.agent.tokens.UpdateReplicationToken(args.Token, token_store.TokenSourceAPI)
|
||||
|
|
|
@ -5396,7 +5396,7 @@ func TestAgent_Token(t *testing.T) {
|
|||
resetTokens := func(init tokens) {
|
||||
a.tokens.UpdateUserToken(init.user, init.userSource)
|
||||
a.tokens.UpdateAgentToken(init.agent, init.agentSource)
|
||||
a.tokens.UpdateAgentMasterToken(init.master, init.masterSource)
|
||||
a.tokens.UpdateAgentRecoveryToken(init.master, init.masterSource)
|
||||
a.tokens.UpdateReplicationToken(init.repl, init.replSource)
|
||||
}
|
||||
|
||||
|
@ -5614,7 +5614,7 @@ func TestAgent_Token(t *testing.T) {
|
|||
}
|
||||
require.Equal(t, tt.effective.user, a.tokens.UserToken())
|
||||
require.Equal(t, tt.effective.agent, a.tokens.AgentToken())
|
||||
require.Equal(t, tt.effective.master, a.tokens.AgentMasterToken())
|
||||
require.Equal(t, tt.effective.master, a.tokens.AgentRecoveryToken())
|
||||
require.Equal(t, tt.effective.repl, a.tokens.ReplicationToken())
|
||||
|
||||
tok, src := a.tokens.UserTokenAndSource()
|
||||
|
@ -5625,7 +5625,7 @@ func TestAgent_Token(t *testing.T) {
|
|||
require.Equal(t, tt.raw.agent, tok)
|
||||
require.Equal(t, tt.raw.agentSource, src)
|
||||
|
||||
tok, src = a.tokens.AgentMasterTokenAndSource()
|
||||
tok, src = a.tokens.AgentRecoveryTokenAndSource()
|
||||
require.Equal(t, tt.raw.master, tok)
|
||||
require.Equal(t, tt.raw.masterSource, src)
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ func TestAgent_TokenStore(t *testing.T) {
|
|||
if got, want := a.tokens.AgentToken(), "agent"; got != want {
|
||||
t.Fatalf("got %q want %q", got, want)
|
||||
}
|
||||
if got, want := a.tokens.IsAgentMasterToken("master"), true; got != want {
|
||||
if got, want := a.tokens.IsAgentRecoveryToken("master"), true; got != want {
|
||||
t.Fatalf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -866,12 +866,12 @@ func (b *builder) build() (rt RuntimeConfig, err error) {
|
|||
ACLTokenReplication: boolVal(c.ACL.TokenReplication),
|
||||
|
||||
ACLTokens: token.Config{
|
||||
DataDir: dataDir,
|
||||
EnablePersistence: boolValWithDefault(c.ACL.EnableTokenPersistence, false),
|
||||
ACLDefaultToken: stringVal(c.ACL.Tokens.Default),
|
||||
ACLAgentToken: stringVal(c.ACL.Tokens.Agent),
|
||||
ACLAgentMasterToken: stringVal(c.ACL.Tokens.AgentRecovery),
|
||||
ACLReplicationToken: stringVal(c.ACL.Tokens.Replication),
|
||||
DataDir: dataDir,
|
||||
EnablePersistence: boolValWithDefault(c.ACL.EnableTokenPersistence, false),
|
||||
ACLDefaultToken: stringVal(c.ACL.Tokens.Default),
|
||||
ACLAgentToken: stringVal(c.ACL.Tokens.Agent),
|
||||
ACLAgentRecoveryToken: stringVal(c.ACL.Tokens.AgentRecovery),
|
||||
ACLReplicationToken: stringVal(c.ACL.Tokens.Replication),
|
||||
},
|
||||
|
||||
// Autopilot
|
||||
|
|
|
@ -111,7 +111,7 @@ func TestLoad_DeprecatedConfig_ACLMasterTokens(t *testing.T) {
|
|||
|
||||
rt := result.RuntimeConfig
|
||||
require.Equal("token1", rt.ACLMasterToken)
|
||||
require.Equal("token2", rt.ACLTokens.ACLAgentMasterToken)
|
||||
require.Equal("token2", rt.ACLTokens.ACLAgentRecoveryToken)
|
||||
})
|
||||
|
||||
t.Run("embedded in tokens struct", func(t *testing.T) {
|
||||
|
@ -142,7 +142,7 @@ func TestLoad_DeprecatedConfig_ACLMasterTokens(t *testing.T) {
|
|||
|
||||
rt := result.RuntimeConfig
|
||||
require.Equal("token1", rt.ACLMasterToken)
|
||||
require.Equal("token2", rt.ACLTokens.ACLAgentMasterToken)
|
||||
require.Equal("token2", rt.ACLTokens.ACLAgentRecoveryToken)
|
||||
})
|
||||
|
||||
t.Run("both", func(t *testing.T) {
|
||||
|
@ -170,6 +170,6 @@ func TestLoad_DeprecatedConfig_ACLMasterTokens(t *testing.T) {
|
|||
|
||||
rt := result.RuntimeConfig
|
||||
require.Equal("token3", rt.ACLMasterToken)
|
||||
require.Equal("token4", rt.ACLTokens.ACLAgentMasterToken)
|
||||
require.Equal("token4", rt.ACLTokens.ACLAgentRecoveryToken)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -5341,12 +5341,12 @@ func TestLoad_FullConfig(t *testing.T) {
|
|||
// user configurable values
|
||||
|
||||
ACLTokens: token.Config{
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "418fdff1",
|
||||
ACLAgentToken: "bed2377c",
|
||||
ACLAgentMasterToken: "1dba6aba",
|
||||
ACLReplicationToken: "5795983a",
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "418fdff1",
|
||||
ACLAgentToken: "bed2377c",
|
||||
ACLAgentRecoveryToken: "1dba6aba",
|
||||
ACLReplicationToken: "5795983a",
|
||||
},
|
||||
|
||||
ACLsEnabled: true,
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
},
|
||||
"ACLTokenReplication": false,
|
||||
"ACLTokens": {
|
||||
"ACLAgentMasterToken": "hidden",
|
||||
"ACLAgentRecoveryToken": "hidden",
|
||||
"ACLAgentToken": "hidden",
|
||||
"ACLDefaultToken": "hidden",
|
||||
"ACLReplicationToken": "hidden",
|
||||
|
@ -424,4 +424,4 @@
|
|||
"Version": "",
|
||||
"VersionPrerelease": "",
|
||||
"Watches": []
|
||||
}
|
||||
}
|
|
@ -1053,7 +1053,7 @@ func (r *ACLResolver) resolveLocallyManagedToken(token string) (structs.ACLIdent
|
|||
return nil, nil, false
|
||||
}
|
||||
|
||||
if r.tokens.IsAgentMasterToken(token) {
|
||||
if r.tokens.IsAgentRecoveryToken(token) {
|
||||
return structs.NewAgentMasterTokenIdentity(r.config.NodeName, token), r.agentMasterAuthz, true
|
||||
}
|
||||
|
||||
|
|
|
@ -4020,7 +4020,7 @@ func TestACLResolver_AgentMaster(t *testing.T) {
|
|||
cfg.DisableDuration = 0
|
||||
})
|
||||
|
||||
tokens.UpdateAgentMasterToken("9a184a11-5599-459e-b71a-550e5f9a5a23", token.TokenSourceConfig)
|
||||
tokens.UpdateAgentRecoveryToken("9a184a11-5599-459e-b71a-550e5f9a5a23", token.TokenSourceConfig)
|
||||
|
||||
ident, authz, err := r.ResolveTokenToIdentityAndAuthorizer("9a184a11-5599-459e-b71a-550e5f9a5a23")
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -17,12 +17,12 @@ type Logger interface {
|
|||
|
||||
// Config used by Store.Load, which includes tokens and settings for persistence.
|
||||
type Config struct {
|
||||
EnablePersistence bool
|
||||
DataDir string
|
||||
ACLDefaultToken string
|
||||
ACLAgentToken string
|
||||
ACLAgentMasterToken string
|
||||
ACLReplicationToken string
|
||||
EnablePersistence bool
|
||||
DataDir string
|
||||
ACLDefaultToken string
|
||||
ACLAgentToken string
|
||||
ACLAgentRecoveryToken string
|
||||
ACLReplicationToken string
|
||||
|
||||
EnterpriseConfig
|
||||
}
|
||||
|
@ -69,10 +69,10 @@ func (t *Store) WithPersistenceLock(f func() error) error {
|
|||
}
|
||||
|
||||
type persistedTokens struct {
|
||||
Replication string `json:"replication,omitempty"`
|
||||
AgentMaster string `json:"agent_master,omitempty"`
|
||||
Default string `json:"default,omitempty"`
|
||||
Agent string `json:"agent,omitempty"`
|
||||
Replication string `json:"replication,omitempty"`
|
||||
AgentRecovery string `json:"agent_recovery,omitempty"`
|
||||
Default string `json:"default,omitempty"`
|
||||
Agent string `json:"agent,omitempty"`
|
||||
}
|
||||
|
||||
type fileStore struct {
|
||||
|
@ -110,14 +110,14 @@ func loadTokens(s *Store, cfg Config, tokens persistedTokens, logger Logger) {
|
|||
s.UpdateAgentToken(cfg.ACLAgentToken, TokenSourceConfig)
|
||||
}
|
||||
|
||||
if tokens.AgentMaster != "" {
|
||||
s.UpdateAgentMasterToken(tokens.AgentMaster, TokenSourceAPI)
|
||||
if tokens.AgentRecovery != "" {
|
||||
s.UpdateAgentRecoveryToken(tokens.AgentRecovery, TokenSourceAPI)
|
||||
|
||||
if cfg.ACLAgentMasterToken != "" {
|
||||
logger.Warn("\"agent_master\" token present in both the configuration and persisted token store, using the persisted token")
|
||||
if cfg.ACLAgentRecoveryToken != "" {
|
||||
logger.Warn("\"agent_recovery\" token present in both the configuration and persisted token store, using the persisted token")
|
||||
}
|
||||
} else {
|
||||
s.UpdateAgentMasterToken(cfg.ACLAgentMasterToken, TokenSourceConfig)
|
||||
s.UpdateAgentRecoveryToken(cfg.ACLAgentRecoveryToken, TokenSourceConfig)
|
||||
}
|
||||
|
||||
if tokens.Replication != "" {
|
||||
|
@ -134,22 +134,32 @@ func loadTokens(s *Store, cfg Config, tokens persistedTokens, logger Logger) {
|
|||
}
|
||||
|
||||
func readPersistedFromFile(filename string) (persistedTokens, error) {
|
||||
tokens := persistedTokens{}
|
||||
var tokens struct {
|
||||
persistedTokens
|
||||
|
||||
// Support reading tokens persisted by versions <1.11, where agent_master was
|
||||
// renamed to agent_recovery.
|
||||
LegacyAgentMaster string `json:"agent_master"`
|
||||
}
|
||||
|
||||
buf, err := ioutil.ReadFile(filename)
|
||||
switch {
|
||||
case os.IsNotExist(err):
|
||||
// non-existence is not an error we care about
|
||||
return tokens, nil
|
||||
return tokens.persistedTokens, nil
|
||||
case err != nil:
|
||||
return tokens, fmt.Errorf("failed reading tokens file %q: %w", filename, err)
|
||||
return tokens.persistedTokens, fmt.Errorf("failed reading tokens file %q: %w", filename, err)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(buf, &tokens); err != nil {
|
||||
return tokens, fmt.Errorf("failed to decode tokens file %q: %w", filename, err)
|
||||
return tokens.persistedTokens, fmt.Errorf("failed to decode tokens file %q: %w", filename, err)
|
||||
}
|
||||
|
||||
return tokens, nil
|
||||
if tokens.AgentRecovery == "" {
|
||||
tokens.AgentRecovery = tokens.LegacyAgentMaster
|
||||
}
|
||||
|
||||
return tokens.persistedTokens, nil
|
||||
}
|
||||
|
||||
func (p *fileStore) withPersistenceLock(s *Store, f func() error) error {
|
||||
|
@ -170,8 +180,8 @@ func (p *fileStore) saveToFile(s *Store) error {
|
|||
tokens.Agent = tok
|
||||
}
|
||||
|
||||
if tok, source := s.AgentMasterTokenAndSource(); tok != "" && source == TokenSourceAPI {
|
||||
tokens.AgentMaster = tok
|
||||
if tok, source := s.AgentRecoveryTokenAndSource(); tok != "" && source == TokenSourceAPI {
|
||||
tokens.AgentRecovery = tok
|
||||
}
|
||||
|
||||
if tok, source := s.ReplicationTokenAndSource(); tok != "" && source == TokenSourceAPI {
|
||||
|
|
|
@ -18,47 +18,47 @@ func TestStore_Load(t *testing.T) {
|
|||
|
||||
t.Run("with empty store", func(t *testing.T) {
|
||||
cfg := Config{
|
||||
DataDir: dataDir,
|
||||
ACLAgentToken: "alfa",
|
||||
ACLAgentMasterToken: "bravo",
|
||||
ACLDefaultToken: "charlie",
|
||||
ACLReplicationToken: "delta",
|
||||
DataDir: dataDir,
|
||||
ACLAgentToken: "alfa",
|
||||
ACLAgentRecoveryToken: "bravo",
|
||||
ACLDefaultToken: "charlie",
|
||||
ACLReplicationToken: "delta",
|
||||
}
|
||||
require.NoError(t, store.Load(cfg, logger))
|
||||
require.Equal(t, "alfa", store.AgentToken())
|
||||
require.Equal(t, "bravo", store.AgentMasterToken())
|
||||
require.Equal(t, "bravo", store.AgentRecoveryToken())
|
||||
require.Equal(t, "charlie", store.UserToken())
|
||||
require.Equal(t, "delta", store.ReplicationToken())
|
||||
})
|
||||
|
||||
t.Run("updated from Config", func(t *testing.T) {
|
||||
cfg := Config{
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "echo",
|
||||
ACLAgentToken: "foxtrot",
|
||||
ACLAgentMasterToken: "golf",
|
||||
ACLReplicationToken: "hotel",
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "echo",
|
||||
ACLAgentToken: "foxtrot",
|
||||
ACLAgentRecoveryToken: "golf",
|
||||
ACLReplicationToken: "hotel",
|
||||
}
|
||||
// ensures no error for missing persisted tokens file
|
||||
require.NoError(t, store.Load(cfg, logger))
|
||||
require.Equal(t, "echo", store.UserToken())
|
||||
require.Equal(t, "foxtrot", store.AgentToken())
|
||||
require.Equal(t, "golf", store.AgentMasterToken())
|
||||
require.Equal(t, "golf", store.AgentRecoveryToken())
|
||||
require.Equal(t, "hotel", store.ReplicationToken())
|
||||
})
|
||||
|
||||
t.Run("with persisted tokens", func(t *testing.T) {
|
||||
cfg := Config{
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "echo",
|
||||
ACLAgentToken: "foxtrot",
|
||||
ACLAgentMasterToken: "golf",
|
||||
ACLReplicationToken: "hotel",
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "echo",
|
||||
ACLAgentToken: "foxtrot",
|
||||
ACLAgentRecoveryToken: "golf",
|
||||
ACLReplicationToken: "hotel",
|
||||
}
|
||||
|
||||
tokens := `{
|
||||
"agent" : "india",
|
||||
"agent_master" : "juliett",
|
||||
"agent_recovery" : "juliett",
|
||||
"default": "kilo",
|
||||
"replication" : "lima"
|
||||
}`
|
||||
|
@ -69,14 +69,14 @@ func TestStore_Load(t *testing.T) {
|
|||
// no updates since token persistence is not enabled
|
||||
require.Equal(t, "echo", store.UserToken())
|
||||
require.Equal(t, "foxtrot", store.AgentToken())
|
||||
require.Equal(t, "golf", store.AgentMasterToken())
|
||||
require.Equal(t, "golf", store.AgentRecoveryToken())
|
||||
require.Equal(t, "hotel", store.ReplicationToken())
|
||||
|
||||
cfg.EnablePersistence = true
|
||||
require.NoError(t, store.Load(cfg, logger))
|
||||
|
||||
require.Equal(t, "india", store.AgentToken())
|
||||
require.Equal(t, "juliett", store.AgentMasterToken())
|
||||
require.Equal(t, "juliett", store.AgentRecoveryToken())
|
||||
require.Equal(t, "kilo", store.UserToken())
|
||||
require.Equal(t, "lima", store.ReplicationToken())
|
||||
|
||||
|
@ -84,28 +84,42 @@ func TestStore_Load(t *testing.T) {
|
|||
require.NotNil(t, store.persistence)
|
||||
})
|
||||
|
||||
t.Run("persisted tokens include pre-1.11 agent_master naming", func(t *testing.T) {
|
||||
cfg := Config{
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLAgentRecoveryToken: "golf",
|
||||
}
|
||||
|
||||
tokens := `{"agent_master": "juliett"}`
|
||||
require.NoError(t, ioutil.WriteFile(tokenFile, []byte(tokens), 0600))
|
||||
require.NoError(t, store.Load(cfg, logger))
|
||||
|
||||
require.Equal(t, "juliett", store.AgentRecoveryToken())
|
||||
})
|
||||
|
||||
t.Run("with persisted tokens, persisted tokens override config", func(t *testing.T) {
|
||||
tokens := `{
|
||||
"agent" : "mike",
|
||||
"agent_master" : "november",
|
||||
"agent_recovery" : "november",
|
||||
"default": "oscar",
|
||||
"replication" : "papa"
|
||||
}`
|
||||
|
||||
cfg := Config{
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "quebec",
|
||||
ACLAgentToken: "romeo",
|
||||
ACLAgentMasterToken: "sierra",
|
||||
ACLReplicationToken: "tango",
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "quebec",
|
||||
ACLAgentToken: "romeo",
|
||||
ACLAgentRecoveryToken: "sierra",
|
||||
ACLReplicationToken: "tango",
|
||||
}
|
||||
|
||||
require.NoError(t, ioutil.WriteFile(tokenFile, []byte(tokens), 0600))
|
||||
require.NoError(t, store.Load(cfg, logger))
|
||||
|
||||
require.Equal(t, "mike", store.AgentToken())
|
||||
require.Equal(t, "november", store.AgentMasterToken())
|
||||
require.Equal(t, "november", store.AgentRecoveryToken())
|
||||
require.Equal(t, "oscar", store.UserToken())
|
||||
require.Equal(t, "papa", store.ReplicationToken())
|
||||
})
|
||||
|
@ -113,35 +127,35 @@ func TestStore_Load(t *testing.T) {
|
|||
t.Run("with some persisted tokens", func(t *testing.T) {
|
||||
tokens := `{
|
||||
"agent" : "uniform",
|
||||
"agent_master" : "victor"
|
||||
"agent_recovery" : "victor"
|
||||
}`
|
||||
|
||||
cfg := Config{
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "whiskey",
|
||||
ACLAgentToken: "xray",
|
||||
ACLAgentMasterToken: "yankee",
|
||||
ACLReplicationToken: "zulu",
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "whiskey",
|
||||
ACLAgentToken: "xray",
|
||||
ACLAgentRecoveryToken: "yankee",
|
||||
ACLReplicationToken: "zulu",
|
||||
}
|
||||
|
||||
require.NoError(t, ioutil.WriteFile(tokenFile, []byte(tokens), 0600))
|
||||
require.NoError(t, store.Load(cfg, logger))
|
||||
|
||||
require.Equal(t, "uniform", store.AgentToken())
|
||||
require.Equal(t, "victor", store.AgentMasterToken())
|
||||
require.Equal(t, "victor", store.AgentRecoveryToken())
|
||||
require.Equal(t, "whiskey", store.UserToken())
|
||||
require.Equal(t, "zulu", store.ReplicationToken())
|
||||
})
|
||||
|
||||
t.Run("persisted file contains invalid data", func(t *testing.T) {
|
||||
cfg := Config{
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "one",
|
||||
ACLAgentToken: "two",
|
||||
ACLAgentMasterToken: "three",
|
||||
ACLReplicationToken: "four",
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "one",
|
||||
ACLAgentToken: "two",
|
||||
ACLAgentRecoveryToken: "three",
|
||||
ACLReplicationToken: "four",
|
||||
}
|
||||
|
||||
require.NoError(t, ioutil.WriteFile(tokenFile, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, 0600))
|
||||
|
@ -151,18 +165,18 @@ func TestStore_Load(t *testing.T) {
|
|||
|
||||
require.Equal(t, "one", store.UserToken())
|
||||
require.Equal(t, "two", store.AgentToken())
|
||||
require.Equal(t, "three", store.AgentMasterToken())
|
||||
require.Equal(t, "three", store.AgentRecoveryToken())
|
||||
require.Equal(t, "four", store.ReplicationToken())
|
||||
})
|
||||
|
||||
t.Run("persisted file contains invalid json", func(t *testing.T) {
|
||||
cfg := Config{
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "alfa",
|
||||
ACLAgentToken: "bravo",
|
||||
ACLAgentMasterToken: "charlie",
|
||||
ACLReplicationToken: "foxtrot",
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "alfa",
|
||||
ACLAgentToken: "bravo",
|
||||
ACLAgentRecoveryToken: "charlie",
|
||||
ACLReplicationToken: "foxtrot",
|
||||
}
|
||||
|
||||
require.NoError(t, ioutil.WriteFile(tokenFile, []byte("[1,2,3]"), 0600))
|
||||
|
@ -172,7 +186,7 @@ func TestStore_Load(t *testing.T) {
|
|||
|
||||
require.Equal(t, "alfa", store.UserToken())
|
||||
require.Equal(t, "bravo", store.AgentToken())
|
||||
require.Equal(t, "charlie", store.AgentMasterToken())
|
||||
require.Equal(t, "charlie", store.AgentRecoveryToken())
|
||||
require.Equal(t, "foxtrot", store.ReplicationToken())
|
||||
})
|
||||
}
|
||||
|
@ -181,12 +195,12 @@ func TestStore_WithPersistenceLock(t *testing.T) {
|
|||
dataDir := testutil.TempDir(t, "datadir")
|
||||
store := new(Store)
|
||||
cfg := Config{
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "default-token",
|
||||
ACLAgentToken: "agent-token",
|
||||
ACLAgentMasterToken: "master-token",
|
||||
ACLReplicationToken: "replication-token",
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "default-token",
|
||||
ACLAgentToken: "agent-token",
|
||||
ACLAgentRecoveryToken: "recovery-token",
|
||||
ACLReplicationToken: "replication-token",
|
||||
}
|
||||
err := store.Load(cfg, hclog.New(nil))
|
||||
require.NoError(t, err)
|
||||
|
@ -195,7 +209,7 @@ func TestStore_WithPersistenceLock(t *testing.T) {
|
|||
updated := store.UpdateUserToken("the-new-token", TokenSourceAPI)
|
||||
require.True(t, updated)
|
||||
|
||||
updated = store.UpdateAgentMasterToken("the-new-master-token", TokenSourceAPI)
|
||||
updated = store.UpdateAgentRecoveryToken("the-new-recovery-token", TokenSourceAPI)
|
||||
require.True(t, updated)
|
||||
return nil
|
||||
}
|
||||
|
@ -206,8 +220,8 @@ func TestStore_WithPersistenceLock(t *testing.T) {
|
|||
tokens, err := readPersistedFromFile(filepath.Join(dataDir, tokensPath))
|
||||
require.NoError(t, err)
|
||||
expected := persistedTokens{
|
||||
Default: "the-new-token",
|
||||
AgentMaster: "the-new-master-token",
|
||||
Default: "the-new-token",
|
||||
AgentRecovery: "the-new-recovery-token",
|
||||
}
|
||||
require.Equal(t, expected, tokens)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ type TokenKind int
|
|||
|
||||
const (
|
||||
TokenKindAgent TokenKind = iota
|
||||
TokenKindAgentMaster
|
||||
TokenKindAgentRecovery
|
||||
TokenKindUser
|
||||
TokenKindReplication
|
||||
)
|
||||
|
@ -59,13 +59,13 @@ type Store struct {
|
|||
// agentTokenSource indicates where this token originated from
|
||||
agentTokenSource TokenSource
|
||||
|
||||
// agentMasterToken is a special token that's only used locally for
|
||||
// agentRecoveryToken is a special token that's only used locally for
|
||||
// access to the /v1/agent utility operations if the servers aren't
|
||||
// available.
|
||||
agentMasterToken string
|
||||
agentRecoveryToken string
|
||||
|
||||
// agentMasterTokenSource indicates where this token originated from
|
||||
agentMasterTokenSource TokenSource
|
||||
// agentRecoveryTokenSource indicates where this token originated from
|
||||
agentRecoveryTokenSource TokenSource
|
||||
|
||||
// replicationToken is a special token that's used by servers to
|
||||
// replicate data from the primary datacenter.
|
||||
|
@ -188,15 +188,15 @@ func (t *Store) UpdateAgentToken(token string, source TokenSource) bool {
|
|||
return changed
|
||||
}
|
||||
|
||||
// UpdateAgentMasterToken replaces the current agent master token in the store.
|
||||
// UpdateAgentRecoveryToken replaces the current agent recovery token in the store.
|
||||
// Returns true if it was changed.
|
||||
func (t *Store) UpdateAgentMasterToken(token string, source TokenSource) bool {
|
||||
func (t *Store) UpdateAgentRecoveryToken(token string, source TokenSource) bool {
|
||||
t.l.Lock()
|
||||
changed := t.agentMasterToken != token || t.agentMasterTokenSource != source
|
||||
t.agentMasterToken = token
|
||||
t.agentMasterTokenSource = source
|
||||
changed := t.agentRecoveryToken != token || t.agentRecoveryTokenSource != source
|
||||
t.agentRecoveryToken = token
|
||||
t.agentRecoveryTokenSource = source
|
||||
if changed {
|
||||
t.sendNotificationLocked(TokenKindAgentMaster)
|
||||
t.sendNotificationLocked(TokenKindAgentRecovery)
|
||||
}
|
||||
t.l.Unlock()
|
||||
return changed
|
||||
|
@ -239,11 +239,11 @@ func (t *Store) AgentToken() string {
|
|||
return t.userToken
|
||||
}
|
||||
|
||||
func (t *Store) AgentMasterToken() string {
|
||||
func (t *Store) AgentRecoveryToken() string {
|
||||
t.l.RLock()
|
||||
defer t.l.RUnlock()
|
||||
|
||||
return t.agentMasterToken
|
||||
return t.agentRecoveryToken
|
||||
}
|
||||
|
||||
// ReplicationToken returns the replication token.
|
||||
|
@ -270,11 +270,11 @@ func (t *Store) AgentTokenAndSource() (string, TokenSource) {
|
|||
return t.agentToken, t.agentTokenSource
|
||||
}
|
||||
|
||||
func (t *Store) AgentMasterTokenAndSource() (string, TokenSource) {
|
||||
func (t *Store) AgentRecoveryTokenAndSource() (string, TokenSource) {
|
||||
t.l.RLock()
|
||||
defer t.l.RUnlock()
|
||||
|
||||
return t.agentMasterToken, t.agentMasterTokenSource
|
||||
return t.agentRecoveryToken, t.agentRecoveryTokenSource
|
||||
}
|
||||
|
||||
// ReplicationToken returns the replication token.
|
||||
|
@ -285,11 +285,11 @@ func (t *Store) ReplicationTokenAndSource() (string, TokenSource) {
|
|||
return t.replicationToken, t.replicationTokenSource
|
||||
}
|
||||
|
||||
// IsAgentMasterToken checks to see if a given token is the agent master token.
|
||||
// IsAgentRecoveryToken checks to see if a given token is the agent recovery token.
|
||||
// This will never match an empty token for safety.
|
||||
func (t *Store) IsAgentMasterToken(token string) bool {
|
||||
func (t *Store) IsAgentRecoveryToken(token string) bool {
|
||||
t.l.RLock()
|
||||
defer t.l.RUnlock()
|
||||
|
||||
return (token != "") && (subtle.ConstantTimeCompare([]byte(token), []byte(t.agentMasterToken)) == 1)
|
||||
return (token != "") && (subtle.ConstantTimeCompare([]byte(token), []byte(t.agentRecoveryToken)) == 1)
|
||||
}
|
||||
|
|
|
@ -8,14 +8,14 @@ import (
|
|||
|
||||
func TestStore_RegularTokens(t *testing.T) {
|
||||
type tokens struct {
|
||||
userSource TokenSource
|
||||
user string
|
||||
agent string
|
||||
agentSource TokenSource
|
||||
master string
|
||||
masterSource TokenSource
|
||||
repl string
|
||||
replSource TokenSource
|
||||
userSource TokenSource
|
||||
user string
|
||||
agent string
|
||||
agentSource TokenSource
|
||||
recovery string
|
||||
recoverySource TokenSource
|
||||
repl string
|
||||
replSource TokenSource
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
|
@ -67,22 +67,22 @@ func TestStore_RegularTokens(t *testing.T) {
|
|||
effective: tokens{repl: "R"},
|
||||
},
|
||||
{
|
||||
name: "set master - config",
|
||||
set: tokens{master: "M", masterSource: TokenSourceConfig},
|
||||
raw: tokens{master: "M", masterSource: TokenSourceConfig},
|
||||
effective: tokens{master: "M"},
|
||||
name: "set recovery - config",
|
||||
set: tokens{recovery: "M", recoverySource: TokenSourceConfig},
|
||||
raw: tokens{recovery: "M", recoverySource: TokenSourceConfig},
|
||||
effective: tokens{recovery: "M"},
|
||||
},
|
||||
{
|
||||
name: "set master - api",
|
||||
set: tokens{master: "M", masterSource: TokenSourceAPI},
|
||||
raw: tokens{master: "M", masterSource: TokenSourceAPI},
|
||||
effective: tokens{master: "M"},
|
||||
name: "set recovery - api",
|
||||
set: tokens{recovery: "M", recoverySource: TokenSourceAPI},
|
||||
raw: tokens{recovery: "M", recoverySource: TokenSourceAPI},
|
||||
effective: tokens{recovery: "M"},
|
||||
},
|
||||
{
|
||||
name: "set all",
|
||||
set: tokens{user: "U", agent: "A", repl: "R", master: "M"},
|
||||
raw: tokens{user: "U", agent: "A", repl: "R", master: "M"},
|
||||
effective: tokens{user: "U", agent: "A", repl: "R", master: "M"},
|
||||
set: tokens{user: "U", agent: "A", repl: "R", recovery: "M"},
|
||||
raw: tokens{user: "U", agent: "A", repl: "R", recovery: "M"},
|
||||
effective: tokens{user: "U", agent: "A", repl: "R", recovery: "M"},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
@ -100,19 +100,19 @@ func TestStore_RegularTokens(t *testing.T) {
|
|||
require.True(t, s.UpdateReplicationToken(tt.set.repl, tt.set.replSource))
|
||||
}
|
||||
|
||||
if tt.set.master != "" {
|
||||
require.True(t, s.UpdateAgentMasterToken(tt.set.master, tt.set.masterSource))
|
||||
if tt.set.recovery != "" {
|
||||
require.True(t, s.UpdateAgentRecoveryToken(tt.set.recovery, tt.set.recoverySource))
|
||||
}
|
||||
|
||||
// If they don't change then they return false.
|
||||
require.False(t, s.UpdateUserToken(tt.set.user, tt.set.userSource))
|
||||
require.False(t, s.UpdateAgentToken(tt.set.agent, tt.set.agentSource))
|
||||
require.False(t, s.UpdateReplicationToken(tt.set.repl, tt.set.replSource))
|
||||
require.False(t, s.UpdateAgentMasterToken(tt.set.master, tt.set.masterSource))
|
||||
require.False(t, s.UpdateAgentRecoveryToken(tt.set.recovery, tt.set.recoverySource))
|
||||
|
||||
require.Equal(t, tt.effective.user, s.UserToken())
|
||||
require.Equal(t, tt.effective.agent, s.AgentToken())
|
||||
require.Equal(t, tt.effective.master, s.AgentMasterToken())
|
||||
require.Equal(t, tt.effective.recovery, s.AgentRecoveryToken())
|
||||
require.Equal(t, tt.effective.repl, s.ReplicationToken())
|
||||
|
||||
tok, src := s.UserTokenAndSource()
|
||||
|
@ -123,9 +123,9 @@ func TestStore_RegularTokens(t *testing.T) {
|
|||
require.Equal(t, tt.raw.agent, tok)
|
||||
require.Equal(t, tt.raw.agentSource, src)
|
||||
|
||||
tok, src = s.AgentMasterTokenAndSource()
|
||||
require.Equal(t, tt.raw.master, tok)
|
||||
require.Equal(t, tt.raw.masterSource, src)
|
||||
tok, src = s.AgentRecoveryTokenAndSource()
|
||||
require.Equal(t, tt.raw.recovery, tok)
|
||||
require.Equal(t, tt.raw.recoverySource, src)
|
||||
|
||||
tok, src = s.ReplicationTokenAndSource()
|
||||
require.Equal(t, tt.raw.repl, tok)
|
||||
|
@ -134,27 +134,27 @@ func TestStore_RegularTokens(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestStore_AgentMasterToken(t *testing.T) {
|
||||
func TestStore_AgentRecoveryToken(t *testing.T) {
|
||||
s := new(Store)
|
||||
|
||||
verify := func(want bool, toks ...string) {
|
||||
for _, tok := range toks {
|
||||
require.Equal(t, want, s.IsAgentMasterToken(tok))
|
||||
require.Equal(t, want, s.IsAgentRecoveryToken(tok))
|
||||
}
|
||||
}
|
||||
|
||||
verify(false, "", "nope")
|
||||
|
||||
s.UpdateAgentMasterToken("master", TokenSourceConfig)
|
||||
verify(true, "master")
|
||||
s.UpdateAgentRecoveryToken("recovery", TokenSourceConfig)
|
||||
verify(true, "recovery")
|
||||
verify(false, "", "nope")
|
||||
|
||||
s.UpdateAgentMasterToken("another", TokenSourceConfig)
|
||||
s.UpdateAgentRecoveryToken("another", TokenSourceConfig)
|
||||
verify(true, "another")
|
||||
verify(false, "", "nope", "master")
|
||||
verify(false, "", "nope", "recovery")
|
||||
|
||||
s.UpdateAgentMasterToken("", TokenSourceConfig)
|
||||
verify(false, "", "nope", "master", "another")
|
||||
s.UpdateAgentRecoveryToken("", TokenSourceConfig)
|
||||
verify(false, "", "nope", "recovery", "another")
|
||||
}
|
||||
|
||||
func TestStore_Notify(t *testing.T) {
|
||||
|
@ -180,7 +180,7 @@ func TestStore_Notify(t *testing.T) {
|
|||
|
||||
agentNotifier := newNotification(t, s, TokenKindAgent)
|
||||
userNotifier := newNotification(t, s, TokenKindUser)
|
||||
agentMasterNotifier := newNotification(t, s, TokenKindAgentMaster)
|
||||
agentRecoveryNotifier := newNotification(t, s, TokenKindAgentRecovery)
|
||||
replicationNotifier := newNotification(t, s, TokenKindReplication)
|
||||
replicationNotifier2 := newNotification(t, s, TokenKindReplication)
|
||||
|
||||
|
@ -193,7 +193,7 @@ func TestStore_Notify(t *testing.T) {
|
|||
requireNotNotified(t, agentNotifier.Ch)
|
||||
requireNotifiedOnce(t, userNotifier.Ch)
|
||||
requireNotNotified(t, replicationNotifier.Ch)
|
||||
requireNotNotified(t, agentMasterNotifier.Ch)
|
||||
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||
requireNotNotified(t, replicationNotifier2.Ch)
|
||||
|
||||
// now update the agent token which should send notificaitons to the agent and all notifier
|
||||
|
@ -202,16 +202,16 @@ func TestStore_Notify(t *testing.T) {
|
|||
requireNotifiedOnce(t, agentNotifier.Ch)
|
||||
requireNotNotified(t, userNotifier.Ch)
|
||||
requireNotNotified(t, replicationNotifier.Ch)
|
||||
requireNotNotified(t, agentMasterNotifier.Ch)
|
||||
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||
requireNotNotified(t, replicationNotifier2.Ch)
|
||||
|
||||
// now update the agent master token which should send notificaitons to the agent master and all notifier
|
||||
require.True(t, s.UpdateAgentMasterToken("789badc8-f850-43e1-8742-9b9f484957cc", TokenSourceAPI))
|
||||
// now update the agent recovery token which should send notificaitons to the agent recovery and all notifier
|
||||
require.True(t, s.UpdateAgentRecoveryToken("789badc8-f850-43e1-8742-9b9f484957cc", TokenSourceAPI))
|
||||
|
||||
requireNotNotified(t, agentNotifier.Ch)
|
||||
requireNotNotified(t, userNotifier.Ch)
|
||||
requireNotNotified(t, replicationNotifier.Ch)
|
||||
requireNotifiedOnce(t, agentMasterNotifier.Ch)
|
||||
requireNotifiedOnce(t, agentRecoveryNotifier.Ch)
|
||||
requireNotNotified(t, replicationNotifier2.Ch)
|
||||
|
||||
// now update the replication token which should send notificaitons to the replication and all notifier
|
||||
|
@ -220,7 +220,7 @@ func TestStore_Notify(t *testing.T) {
|
|||
requireNotNotified(t, agentNotifier.Ch)
|
||||
requireNotNotified(t, userNotifier.Ch)
|
||||
requireNotifiedOnce(t, replicationNotifier.Ch)
|
||||
requireNotNotified(t, agentMasterNotifier.Ch)
|
||||
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||
requireNotifiedOnce(t, replicationNotifier2.Ch)
|
||||
|
||||
s.StopNotify(replicationNotifier2)
|
||||
|
@ -231,12 +231,12 @@ func TestStore_Notify(t *testing.T) {
|
|||
requireNotNotified(t, agentNotifier.Ch)
|
||||
requireNotNotified(t, userNotifier.Ch)
|
||||
requireNotifiedOnce(t, replicationNotifier.Ch)
|
||||
requireNotNotified(t, agentMasterNotifier.Ch)
|
||||
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||
requireNotNotified(t, replicationNotifier2.Ch)
|
||||
|
||||
// request updates but that are not changes
|
||||
require.False(t, s.UpdateAgentToken("5d748ec2-d536-461f-8e2a-1f7eae98d559", TokenSourceAPI))
|
||||
require.False(t, s.UpdateAgentMasterToken("789badc8-f850-43e1-8742-9b9f484957cc", TokenSourceAPI))
|
||||
require.False(t, s.UpdateAgentRecoveryToken("789badc8-f850-43e1-8742-9b9f484957cc", TokenSourceAPI))
|
||||
require.False(t, s.UpdateUserToken("47788919-f944-476a-bda5-446d64be1df8", TokenSourceAPI))
|
||||
require.False(t, s.UpdateReplicationToken("eb0b56b9-fa65-4ae1-902a-c64457c62ac6", TokenSourceAPI))
|
||||
|
||||
|
@ -244,5 +244,5 @@ func TestStore_Notify(t *testing.T) {
|
|||
requireNotNotified(t, agentNotifier.Ch)
|
||||
requireNotNotified(t, userNotifier.Ch)
|
||||
requireNotNotified(t, replicationNotifier.Ch)
|
||||
requireNotNotified(t, agentMasterNotifier.Ch)
|
||||
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue