agent: safer read methods for tokens

This commit is contained in:
Ryan Uber 2015-04-28 11:53:53 -07:00
parent 54b5f17629
commit f069db21e3
5 changed files with 47 additions and 17 deletions

View file

@ -957,7 +957,7 @@ func (a *Agent) loadServices(conf *Config) error {
return err
}
svc := wrapped.Service
a.state.AddServiceToken(svc.ID, wrapped.Token)
a.state.SetServiceToken(svc.ID, wrapped.Token)
if _, ok := a.state.services[svc.ID]; ok {
// Purge previously persisted service. This allows config to be
@ -1029,7 +1029,7 @@ func (a *Agent) loadChecks(conf *Config) error {
if err := json.Unmarshal(content, &p); err != nil {
return err
}
a.state.AddCheckToken(p.Check.CheckID, p.Token)
a.state.SetCheckToken(p.Check.CheckID, p.Token)
if _, ok := a.state.checks[p.Check.CheckID]; ok {
// Purge previously persisted check. This allows config to be

View file

@ -100,7 +100,7 @@ func (s *HTTPServer) AgentRegisterCheck(resp http.ResponseWriter, req *http.Requ
// Get the provided token, if any
var token string
s.parseToken(req, &token)
s.agent.state.AddCheckToken(health.CheckID, token)
s.agent.state.SetCheckToken(health.CheckID, token)
// Add the check
if err := s.agent.AddCheck(health, chkType, true); err != nil {
@ -207,7 +207,7 @@ func (s *HTTPServer) AgentRegisterService(resp http.ResponseWriter, req *http.Re
// Get the provided token, if any
var token string
s.parseToken(req, &token)
s.agent.state.AddServiceToken(ns.ID, token)
s.agent.state.SetServiceToken(ns.ID, token)
// Add the check
if err := s.agent.AddService(ns, chkTypes, true); err != nil {

View file

@ -522,7 +522,7 @@ func TestAgent_PersistService(t *testing.T) {
file := filepath.Join(agent.config.DataDir, servicesDir, stringHash(svc.ID))
// Configure a service token
agent.state.AddServiceToken(svc.ID, "hello")
agent.state.SetServiceToken(svc.ID, "hello")
// Check is not persisted unless requested
if err := agent.AddService(svc, nil, false); err != nil {
@ -677,7 +677,7 @@ func TestAgent_PersistCheck(t *testing.T) {
file := filepath.Join(agent.config.DataDir, checksDir, stringHash(check.CheckID))
// Configure a service registration token
agent.state.AddCheckToken(check.CheckID, "hello")
agent.state.SetCheckToken(check.CheckID, "hello")
// Not persisted if not requested
if err := agent.AddCheck(check, chkType, false); err != nil {

View file

@ -123,9 +123,9 @@ func (l *localState) isPaused() bool {
return atomic.LoadInt32(&l.paused) == 1
}
// AddServiceToken configures the provided token for the service ID.
// SetServiceToken configures the provided token for the service ID.
// The token will be used to perform service registration operations.
func (l *localState) AddServiceToken(id, token string) {
func (l *localState) SetServiceToken(id, token string) {
l.Lock()
defer l.Unlock()
l.serviceTokens[id] = token
@ -133,8 +133,14 @@ func (l *localState) AddServiceToken(id, token string) {
// ServiceToken returns the configured ACL token for the given
// service ID. If none is present, the agent's token is returned.
// Assumes a lock is already established on the state.
func (l *localState) ServiceToken(id string) string {
l.RLock()
defer l.RUnlock()
return l.serviceToken(id)
}
// serviceToken returns an ACL token associated with a service.
func (l *localState) serviceToken(id string) string {
token := l.serviceTokens[id]
if token == "" {
token = l.config.ACLToken
@ -183,18 +189,24 @@ func (l *localState) Services() map[string]*structs.NodeService {
return services
}
// AddCheckToken is used to configure an ACL token for a specific
// SetCheckToken is used to configure an ACL token for a specific
// health check. The token is used during check registration operations.
func (l *localState) AddCheckToken(id, token string) {
func (l *localState) SetCheckToken(id, token string) {
l.Lock()
defer l.Unlock()
l.checkTokens[id] = token
}
// CheckToken is used to return the configured health check token, or
// if none is configured, the default agent ACL token. Assumes a lock
// has already been taken on the state.
// if none is configured, the default agent ACL token.
func (l *localState) CheckToken(id string) string {
l.RLock()
defer l.RUnlock()
return l.checkToken(id)
}
// checkToken returns an ACL token associated with a check.
func (l *localState) checkToken(id string) string {
token := l.checkTokens[id]
if token == "" {
token = l.config.ACLToken
@ -482,7 +494,7 @@ func (l *localState) deleteService(id string) error {
Datacenter: l.config.Datacenter,
Node: l.config.NodeName,
ServiceID: id,
WriteRequest: structs.WriteRequest{Token: l.ServiceToken(id)},
WriteRequest: structs.WriteRequest{Token: l.serviceToken(id)},
}
var out struct{}
err := l.iface.RPC("Catalog.Deregister", &req, &out)
@ -503,7 +515,7 @@ func (l *localState) deleteCheck(id string) error {
Datacenter: l.config.Datacenter,
Node: l.config.NodeName,
CheckID: id,
WriteRequest: structs.WriteRequest{Token: l.CheckToken(id)},
WriteRequest: structs.WriteRequest{Token: l.checkToken(id)},
}
var out struct{}
err := l.iface.RPC("Catalog.Deregister", &req, &out)
@ -521,7 +533,7 @@ func (l *localState) syncService(id string) error {
Node: l.config.NodeName,
Address: l.config.AdvertiseAddr,
Service: l.services[id],
WriteRequest: structs.WriteRequest{Token: l.ServiceToken(id)},
WriteRequest: structs.WriteRequest{Token: l.serviceToken(id)},
}
// If the service has associated checks that are out of sync,
@ -579,7 +591,7 @@ func (l *localState) syncCheck(id string) error {
Address: l.config.AdvertiseAddr,
Service: service,
Check: l.checks[id],
WriteRequest: structs.WriteRequest{Token: l.CheckToken(id)},
WriteRequest: structs.WriteRequest{Token: l.checkToken(id)},
}
var out struct{}
err := l.iface.RPC("Catalog.Register", &req, &out)

View file

@ -615,6 +615,24 @@ func TestAgentAntiEntropy_deleteCheck_fails(t *testing.T) {
}
}
func TestAgent_serviceTokens(t *testing.T) {
l := new(localState)
l.Init()
l.SetServiceToken("redis", "abc123")
if token := l.ServiceToken("redis"); token != "abc123" {
t.Fatalf("bad: %s", token)
}
}
func TestAgent_checkTokens(t *testing.T) {
l := new(localState)
l.Init()
l.SetCheckToken("mem", "abc123")
if token := l.CheckToken("mem"); token != "abc123" {
t.Fatalf("bad: %s", token)
}
}
var testRegisterRules = `
service "api" {
policy = "write"