mirror of https://github.com/status-im/consul.git
Merge pull request #10188 from hashicorp/dnephin/dont-persist-agent-tokens
agent/local: do not persist the agent or user token
This commit is contained in:
parent
763118c1ea
commit
ac0697ac48
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
local: agents will no longer persist the default user token along with a service or check.
|
||||||
|
```
|
|
@ -227,25 +227,25 @@ func (l *State) SetDiscardCheckOutput(b bool) {
|
||||||
l.discardCheckOutput.Store(b)
|
l.discardCheckOutput.Store(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServiceToken returns the configured ACL token for the given
|
// ServiceToken returns the ACL token associated with the service. If the service is
|
||||||
// service ID. If none is present, the agent's token is returned.
|
// not found, or does not have a token, the empty string is returned.
|
||||||
func (l *State) ServiceToken(id structs.ServiceID) string {
|
func (l *State) ServiceToken(id structs.ServiceID) string {
|
||||||
l.RLock()
|
l.RLock()
|
||||||
defer l.RUnlock()
|
defer l.RUnlock()
|
||||||
return l.serviceToken(id)
|
if s := l.services[id]; s != nil {
|
||||||
|
return s.Token
|
||||||
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// serviceToken returns an ACL token associated with a service.
|
// aclTokenForServiceSync returns an ACL token associated with a service. If there is
|
||||||
|
// no ACL token associated with the service, fallback is used to return a value.
|
||||||
// This method is not synchronized and the lock must already be held.
|
// This method is not synchronized and the lock must already be held.
|
||||||
func (l *State) serviceToken(id structs.ServiceID) string {
|
func (l *State) aclTokenForServiceSync(id structs.ServiceID, fallback func() string) string {
|
||||||
var token string
|
if s := l.services[id]; s != nil && s.Token != "" {
|
||||||
if s := l.services[id]; s != nil {
|
return s.Token
|
||||||
token = s.Token
|
|
||||||
}
|
}
|
||||||
if token == "" {
|
return fallback()
|
||||||
token = l.tokens.AgentToken()
|
|
||||||
}
|
|
||||||
return token
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddService is used to add a service entry to the local state.
|
// AddService is used to add a service entry to the local state.
|
||||||
|
@ -440,26 +440,25 @@ func (l *State) ServiceStates(entMeta *structs.EnterpriseMeta) map[structs.Servi
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckToken is used to return the configured health check token for a
|
// CheckToken returns the ACL token associated with the check. If the check is
|
||||||
// Check, or if none is configured, the default agent ACL token.
|
// not found, or does not have a token, the empty string is returned.
|
||||||
func (l *State) CheckToken(checkID structs.CheckID) string {
|
func (l *State) CheckToken(id structs.CheckID) string {
|
||||||
l.RLock()
|
l.RLock()
|
||||||
defer l.RUnlock()
|
defer l.RUnlock()
|
||||||
return l.checkToken(checkID)
|
if c := l.checks[id]; c != nil {
|
||||||
|
return c.Token
|
||||||
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkToken returns an ACL token associated with a check.
|
// aclTokenForCheckSync returns an ACL token associated with a check. If there is
|
||||||
|
// no ACL token associated with the check, the callback is used to return a value.
|
||||||
// This method is not synchronized and the lock must already be held.
|
// This method is not synchronized and the lock must already be held.
|
||||||
func (l *State) checkToken(id structs.CheckID) string {
|
func (l *State) aclTokenForCheckSync(id structs.CheckID, fallback func() string) string {
|
||||||
var token string
|
if c := l.checks[id]; c != nil && c.Token != "" {
|
||||||
c := l.checks[id]
|
return c.Token
|
||||||
if c != nil {
|
|
||||||
token = c.Token
|
|
||||||
}
|
}
|
||||||
if token == "" {
|
return fallback()
|
||||||
token = l.tokens.AgentToken()
|
|
||||||
}
|
|
||||||
return token
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddCheck is used to add a health check to the local state.
|
// AddCheck is used to add a health check to the local state.
|
||||||
|
@ -1132,8 +1131,7 @@ func (l *State) deleteService(key structs.ServiceID) error {
|
||||||
return fmt.Errorf("ServiceID missing")
|
return fmt.Errorf("ServiceID missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
st := l.serviceToken(key)
|
st := l.aclTokenForServiceSync(key, l.tokens.AgentToken)
|
||||||
|
|
||||||
req := structs.DeregisterRequest{
|
req := structs.DeregisterRequest{
|
||||||
Datacenter: l.config.Datacenter,
|
Datacenter: l.config.Datacenter,
|
||||||
Node: l.config.NodeName,
|
Node: l.config.NodeName,
|
||||||
|
@ -1182,7 +1180,7 @@ func (l *State) deleteCheck(key structs.CheckID) error {
|
||||||
return fmt.Errorf("CheckID missing")
|
return fmt.Errorf("CheckID missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
ct := l.checkToken(key)
|
ct := l.aclTokenForCheckSync(key, l.tokens.AgentToken)
|
||||||
req := structs.DeregisterRequest{
|
req := structs.DeregisterRequest{
|
||||||
Datacenter: l.config.Datacenter,
|
Datacenter: l.config.Datacenter,
|
||||||
Node: l.config.NodeName,
|
Node: l.config.NodeName,
|
||||||
|
@ -1226,7 +1224,7 @@ func (l *State) pruneCheck(id structs.CheckID) {
|
||||||
|
|
||||||
// syncService is used to sync a service to the server
|
// syncService is used to sync a service to the server
|
||||||
func (l *State) syncService(key structs.ServiceID) error {
|
func (l *State) syncService(key structs.ServiceID) error {
|
||||||
st := l.serviceToken(key)
|
st := l.aclTokenForServiceSync(key, l.tokens.UserToken)
|
||||||
|
|
||||||
// If the service has associated checks that are out of sync,
|
// If the service has associated checks that are out of sync,
|
||||||
// piggyback them on the service sync so they are part of the
|
// piggyback them on the service sync so they are part of the
|
||||||
|
@ -1242,7 +1240,7 @@ func (l *State) syncService(key structs.ServiceID) error {
|
||||||
if !key.Matches(c.Check.CompoundServiceID()) {
|
if !key.Matches(c.Check.CompoundServiceID()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if st != l.checkToken(checkKey) {
|
if st != l.aclTokenForCheckSync(checkKey, l.tokens.UserToken) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
checks = append(checks, c.Check)
|
checks = append(checks, c.Check)
|
||||||
|
@ -1308,7 +1306,7 @@ func (l *State) syncService(key structs.ServiceID) error {
|
||||||
// syncCheck is used to sync a check to the server
|
// syncCheck is used to sync a check to the server
|
||||||
func (l *State) syncCheck(key structs.CheckID) error {
|
func (l *State) syncCheck(key structs.CheckID) error {
|
||||||
c := l.checks[key]
|
c := l.checks[key]
|
||||||
ct := l.checkToken(key)
|
ct := l.aclTokenForCheckSync(key, l.tokens.UserToken)
|
||||||
req := structs.RegisterRequest{
|
req := structs.RegisterRequest{
|
||||||
Datacenter: l.config.Datacenter,
|
Datacenter: l.config.Datacenter,
|
||||||
ID: l.config.NodeID,
|
ID: l.config.NodeID,
|
||||||
|
|
|
@ -1768,33 +1768,38 @@ func TestAgentAntiEntropy_NodeInfo(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAgent_ServiceTokens(t *testing.T) {
|
func TestState_ServiceTokens(t *testing.T) {
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
tokens := new(token.Store)
|
tokens := new(token.Store)
|
||||||
tokens.UpdateUserToken("default", token.TokenSourceConfig)
|
|
||||||
cfg := loadRuntimeConfig(t, `bind_addr = "127.0.0.1" data_dir = "dummy"`)
|
cfg := loadRuntimeConfig(t, `bind_addr = "127.0.0.1" data_dir = "dummy"`)
|
||||||
l := local.NewState(agent.LocalConfig(cfg), nil, tokens)
|
l := local.NewState(agent.LocalConfig(cfg), nil, tokens)
|
||||||
l.TriggerSyncChanges = func() {}
|
l.TriggerSyncChanges = func() {}
|
||||||
|
|
||||||
l.AddService(&structs.NodeService{ID: "redis"}, "")
|
id := structs.NewServiceID("redis", nil)
|
||||||
|
|
||||||
// Returns default when no token is set
|
t.Run("defaults to empty string", func(t *testing.T) {
|
||||||
if token := l.ServiceToken(structs.NewServiceID("redis", nil)); token != "default" {
|
require.Equal(t, "", l.ServiceToken(id))
|
||||||
t.Fatalf("bad: %s", token)
|
})
|
||||||
}
|
|
||||||
|
|
||||||
// Returns configured token
|
t.Run("empty string when there is no token", func(t *testing.T) {
|
||||||
l.AddService(&structs.NodeService{ID: "redis"}, "abc123")
|
err := l.AddService(&structs.NodeService{ID: "redis"}, "")
|
||||||
if token := l.ServiceToken(structs.NewServiceID("redis", nil)); token != "abc123" {
|
require.NoError(t, err)
|
||||||
t.Fatalf("bad: %s", token)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keeps token around for the delete
|
require.Equal(t, "", l.ServiceToken(id))
|
||||||
l.RemoveService(structs.NewServiceID("redis", nil))
|
})
|
||||||
if token := l.ServiceToken(structs.NewServiceID("redis", nil)); token != "abc123" {
|
|
||||||
t.Fatalf("bad: %s", token)
|
t.Run("returns configured token", func(t *testing.T) {
|
||||||
}
|
err := l.AddService(&structs.NodeService{ID: "redis"}, "abc123")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, "abc123", l.ServiceToken(id))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("RemoveCheck keeps token around for the delete", func(t *testing.T) {
|
||||||
|
err := l.RemoveService(structs.NewServiceID("redis", nil))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, "abc123", l.ServiceToken(id))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadRuntimeConfig(t *testing.T, hcl string) *config.RuntimeConfig {
|
func loadRuntimeConfig(t *testing.T, hcl string) *config.RuntimeConfig {
|
||||||
|
@ -1805,32 +1810,38 @@ func loadRuntimeConfig(t *testing.T, hcl string) *config.RuntimeConfig {
|
||||||
return result.RuntimeConfig
|
return result.RuntimeConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAgent_CheckTokens(t *testing.T) {
|
func TestState_CheckTokens(t *testing.T) {
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
tokens := new(token.Store)
|
tokens := new(token.Store)
|
||||||
tokens.UpdateUserToken("default", token.TokenSourceConfig)
|
|
||||||
cfg := loadRuntimeConfig(t, `bind_addr = "127.0.0.1" data_dir = "dummy"`)
|
cfg := loadRuntimeConfig(t, `bind_addr = "127.0.0.1" data_dir = "dummy"`)
|
||||||
l := local.NewState(agent.LocalConfig(cfg), nil, tokens)
|
l := local.NewState(agent.LocalConfig(cfg), nil, tokens)
|
||||||
l.TriggerSyncChanges = func() {}
|
l.TriggerSyncChanges = func() {}
|
||||||
|
|
||||||
// Returns default when no token is set
|
id := structs.NewCheckID("mem", nil)
|
||||||
l.AddCheck(&structs.HealthCheck{CheckID: types.CheckID("mem")}, "")
|
|
||||||
if token := l.CheckToken(structs.NewCheckID("mem", nil)); token != "default" {
|
|
||||||
t.Fatalf("bad: %s", token)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns configured token
|
t.Run("defaults to empty string", func(t *testing.T) {
|
||||||
l.AddCheck(&structs.HealthCheck{CheckID: types.CheckID("mem")}, "abc123")
|
require.Equal(t, "", l.CheckToken(id))
|
||||||
if token := l.CheckToken(structs.NewCheckID("mem", nil)); token != "abc123" {
|
})
|
||||||
t.Fatalf("bad: %s", token)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keeps token around for the delete
|
t.Run("empty string when there is no token", func(t *testing.T) {
|
||||||
l.RemoveCheck(structs.NewCheckID("mem", nil))
|
err := l.AddCheck(&structs.HealthCheck{CheckID: "mem"}, "")
|
||||||
if token := l.CheckToken(structs.NewCheckID("mem", nil)); token != "abc123" {
|
require.NoError(t, err)
|
||||||
t.Fatalf("bad: %s", token)
|
|
||||||
}
|
require.Equal(t, "", l.CheckToken(id))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("returns configured token", func(t *testing.T) {
|
||||||
|
err := l.AddCheck(&structs.HealthCheck{CheckID: "mem"}, "abc123")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, "abc123", l.CheckToken(id))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("RemoveCheck keeps token around for the delete", func(t *testing.T) {
|
||||||
|
err := l.RemoveCheck(structs.NewCheckID("mem", nil))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, "abc123", l.CheckToken(id))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAgent_CheckCriticalTime(t *testing.T) {
|
func TestAgent_CheckCriticalTime(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue