mirror of
https://github.com/status-im/consul.git
synced 2025-01-11 06:16:08 +00:00
Adds support for a new "acl_agent_token" which is used for internal
catalog operations.
This commit is contained in:
parent
0ed6b1bb18
commit
0139bbb963
@ -227,8 +227,8 @@ func Create(config *Config, logOutput io.Writer, logWriter *logger.LogWriter,
|
|||||||
Port: agent.config.Ports.Server,
|
Port: agent.config.Ports.Server,
|
||||||
Tags: []string{},
|
Tags: []string{},
|
||||||
}
|
}
|
||||||
// TODO (slackpad) - Plumb the "acl_agent_token" into here.
|
|
||||||
agent.state.AddService(&consulService, "")
|
agent.state.AddService(&consulService, agent.config.GetTokenForAgent())
|
||||||
} else {
|
} else {
|
||||||
err = agent.setupClient()
|
err = agent.setupClient()
|
||||||
agent.state.SetIface(agent.client)
|
agent.state.SetIface(agent.client)
|
||||||
@ -364,6 +364,9 @@ func (a *Agent) consulConfig() *consul.Config {
|
|||||||
if a.config.ACLToken != "" {
|
if a.config.ACLToken != "" {
|
||||||
base.ACLToken = a.config.ACLToken
|
base.ACLToken = a.config.ACLToken
|
||||||
}
|
}
|
||||||
|
if a.config.ACLAgentToken != "" {
|
||||||
|
base.ACLAgentToken = a.config.ACLAgentToken
|
||||||
|
}
|
||||||
if a.config.ACLMasterToken != "" {
|
if a.config.ACLMasterToken != "" {
|
||||||
base.ACLMasterToken = a.config.ACLMasterToken
|
base.ACLMasterToken = a.config.ACLMasterToken
|
||||||
}
|
}
|
||||||
|
@ -488,6 +488,11 @@ type Config struct {
|
|||||||
// token is not provided. If not configured the 'anonymous' token is used.
|
// token is not provided. If not configured the 'anonymous' token is used.
|
||||||
ACLToken string `mapstructure:"acl_token" json:"-"`
|
ACLToken string `mapstructure:"acl_token" json:"-"`
|
||||||
|
|
||||||
|
// ACLAgentToken is the default token used to make requests for the agent
|
||||||
|
// itself, such as for registering itself with the catalog. If not
|
||||||
|
// configured, the 'acl_token' will be used.
|
||||||
|
ACLAgentToken string `mapstructure:"acl_agent_token" json:"-"`
|
||||||
|
|
||||||
// ACLMasterToken is used to bootstrap the ACL system. It should be specified
|
// ACLMasterToken is used to bootstrap the ACL system. It should be specified
|
||||||
// on the servers in the ACLDatacenter. When the leader comes online, it ensures
|
// on the servers in the ACLDatacenter. When the leader comes online, it ensures
|
||||||
// that the Master token is available. This provides the initial token.
|
// that the Master token is available. This provides the initial token.
|
||||||
@ -756,6 +761,18 @@ func (c *Config) ClientListener(override string, port int) (net.Addr, error) {
|
|||||||
return &net.TCPAddr{IP: ip, Port: port}, nil
|
return &net.TCPAddr{IP: ip, Port: port}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTokenForAgent returns the token the agent should use for its own internal
|
||||||
|
// operations, such as registering itself with the catalog.
|
||||||
|
func (c *Config) GetTokenForAgent() string {
|
||||||
|
if c.ACLAgentToken != "" {
|
||||||
|
return c.ACLAgentToken
|
||||||
|
} else if c.ACLToken != "" {
|
||||||
|
return c.ACLToken
|
||||||
|
} else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// DecodeConfig reads the configuration from the given reader in JSON
|
// DecodeConfig reads the configuration from the given reader in JSON
|
||||||
// format and decodes it into a proper Config structure.
|
// format and decodes it into a proper Config structure.
|
||||||
func DecodeConfig(r io.Reader) (*Config, error) {
|
func DecodeConfig(r io.Reader) (*Config, error) {
|
||||||
@ -1466,6 +1483,9 @@ func MergeConfig(a, b *Config) *Config {
|
|||||||
if b.ACLToken != "" {
|
if b.ACLToken != "" {
|
||||||
result.ACLToken = b.ACLToken
|
result.ACLToken = b.ACLToken
|
||||||
}
|
}
|
||||||
|
if b.ACLAgentToken != "" {
|
||||||
|
result.ACLAgentToken = b.ACLAgentToken
|
||||||
|
}
|
||||||
if b.ACLMasterToken != "" {
|
if b.ACLMasterToken != "" {
|
||||||
result.ACLMasterToken = b.ACLMasterToken
|
result.ACLMasterToken = b.ACLMasterToken
|
||||||
}
|
}
|
||||||
|
@ -643,7 +643,7 @@ func TestDecodeConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ACLs
|
// ACLs
|
||||||
input = `{"acl_token": "1234", "acl_datacenter": "dc2",
|
input = `{"acl_token": "1234", "acl_agent_token": "5678", "acl_datacenter": "dc2",
|
||||||
"acl_ttl": "60s", "acl_down_policy": "deny",
|
"acl_ttl": "60s", "acl_down_policy": "deny",
|
||||||
"acl_default_policy": "deny", "acl_master_token": "2345",
|
"acl_default_policy": "deny", "acl_master_token": "2345",
|
||||||
"acl_replication_token": "8675309"}`
|
"acl_replication_token": "8675309"}`
|
||||||
@ -655,6 +655,9 @@ func TestDecodeConfig(t *testing.T) {
|
|||||||
if config.ACLToken != "1234" {
|
if config.ACLToken != "1234" {
|
||||||
t.Fatalf("bad: %#v", config)
|
t.Fatalf("bad: %#v", config)
|
||||||
}
|
}
|
||||||
|
if config.ACLAgentToken != "5678" {
|
||||||
|
t.Fatalf("bad: %#v", config)
|
||||||
|
}
|
||||||
if config.ACLMasterToken != "2345" {
|
if config.ACLMasterToken != "2345" {
|
||||||
t.Fatalf("bad: %#v", config)
|
t.Fatalf("bad: %#v", config)
|
||||||
}
|
}
|
||||||
@ -674,6 +677,32 @@ func TestDecodeConfig(t *testing.T) {
|
|||||||
t.Fatalf("bad: %#v", config)
|
t.Fatalf("bad: %#v", config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ACL token precedence.
|
||||||
|
input = `{}`
|
||||||
|
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if token := config.GetTokenForAgent(); token != "" {
|
||||||
|
t.Fatalf("bad: %s", token)
|
||||||
|
}
|
||||||
|
input = `{"acl_token": "hello"}`
|
||||||
|
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if token := config.GetTokenForAgent(); token != "hello" {
|
||||||
|
t.Fatalf("bad: %s", token)
|
||||||
|
}
|
||||||
|
input = `{"acl_agent_token": "world", "acl_token": "hello"}`
|
||||||
|
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if token := config.GetTokenForAgent(); token != "world" {
|
||||||
|
t.Fatalf("bad: %s", token)
|
||||||
|
}
|
||||||
|
|
||||||
// ACL flag for Consul version 0.8 features (broken out since we will
|
// ACL flag for Consul version 0.8 features (broken out since we will
|
||||||
// eventually remove this). We first verify this is opt-out.
|
// eventually remove this). We first verify this is opt-out.
|
||||||
config = DefaultConfig()
|
config = DefaultConfig()
|
||||||
@ -1561,6 +1590,7 @@ func TestMergeConfig(t *testing.T) {
|
|||||||
CheckUpdateInterval: 8 * time.Minute,
|
CheckUpdateInterval: 8 * time.Minute,
|
||||||
CheckUpdateIntervalRaw: "8m",
|
CheckUpdateIntervalRaw: "8m",
|
||||||
ACLToken: "1234",
|
ACLToken: "1234",
|
||||||
|
ACLAgentToken: "5678",
|
||||||
ACLMasterToken: "2345",
|
ACLMasterToken: "2345",
|
||||||
ACLDatacenter: "dc2",
|
ACLDatacenter: "dc2",
|
||||||
ACLTTL: 15 * time.Second,
|
ACLTTL: 15 * time.Second,
|
||||||
|
@ -400,7 +400,7 @@ func (l *localState) setSyncState() error {
|
|||||||
req := structs.NodeSpecificRequest{
|
req := structs.NodeSpecificRequest{
|
||||||
Datacenter: l.config.Datacenter,
|
Datacenter: l.config.Datacenter,
|
||||||
Node: l.config.NodeName,
|
Node: l.config.NodeName,
|
||||||
QueryOptions: structs.QueryOptions{Token: l.config.ACLToken},
|
QueryOptions: structs.QueryOptions{Token: l.config.GetTokenForAgent()},
|
||||||
}
|
}
|
||||||
var out1 structs.IndexedNodeServices
|
var out1 structs.IndexedNodeServices
|
||||||
var out2 structs.IndexedHealthChecks
|
var out2 structs.IndexedHealthChecks
|
||||||
@ -709,7 +709,7 @@ func (l *localState) syncNodeInfo() error {
|
|||||||
Node: l.config.NodeName,
|
Node: l.config.NodeName,
|
||||||
Address: l.config.AdvertiseAddr,
|
Address: l.config.AdvertiseAddr,
|
||||||
TaggedAddresses: l.config.TaggedAddresses,
|
TaggedAddresses: l.config.TaggedAddresses,
|
||||||
WriteRequest: structs.WriteRequest{Token: l.config.ACLToken},
|
WriteRequest: structs.WriteRequest{Token: l.config.GetTokenForAgent()},
|
||||||
}
|
}
|
||||||
var out struct{}
|
var out struct{}
|
||||||
err := l.iface.RPC("Catalog.Register", &req, &out)
|
err := l.iface.RPC("Catalog.Register", &req, &out)
|
||||||
|
@ -155,6 +155,11 @@ type Config struct {
|
|||||||
// backwards compatibility as well.
|
// backwards compatibility as well.
|
||||||
ACLToken string
|
ACLToken string
|
||||||
|
|
||||||
|
// ACLAgentToken is the default token used to make requests for the agent
|
||||||
|
// itself, such as for registering itself with the catalog. If not
|
||||||
|
// configured, the ACLToken will be used.
|
||||||
|
ACLAgentToken string
|
||||||
|
|
||||||
// ACLMasterToken is used to bootstrap the ACL system. It should be specified
|
// ACLMasterToken is used to bootstrap the ACL system. It should be specified
|
||||||
// on the servers in the ACLDatacenter. When the leader comes online, it ensures
|
// on the servers in the ACLDatacenter. When the leader comes online, it ensures
|
||||||
// that the Master token is available. This provides the initial token.
|
// that the Master token is available. This provides the initial token.
|
||||||
@ -370,6 +375,7 @@ func (c *Config) ScaleRaft(raftMultRaw uint) {
|
|||||||
c.RaftConfig.LeaderLeaseTimeout = raftMult * def.LeaderLeaseTimeout
|
c.RaftConfig.LeaderLeaseTimeout = raftMult * def.LeaderLeaseTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tlsConfig maps this config into a tlsutil config.
|
||||||
func (c *Config) tlsConfig() *tlsutil.Config {
|
func (c *Config) tlsConfig() *tlsutil.Config {
|
||||||
tlsConf := &tlsutil.Config{
|
tlsConf := &tlsutil.Config{
|
||||||
VerifyIncoming: c.VerifyIncoming,
|
VerifyIncoming: c.VerifyIncoming,
|
||||||
@ -384,3 +390,15 @@ func (c *Config) tlsConfig() *tlsutil.Config {
|
|||||||
}
|
}
|
||||||
return tlsConf
|
return tlsConf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTokenForAgent returns the token the agent should use for its own internal
|
||||||
|
// operations, such as registering itself with the catalog.
|
||||||
|
func (c *Config) GetTokenForAgent() string {
|
||||||
|
if c.ACLAgentToken != "" {
|
||||||
|
return c.ACLAgentToken
|
||||||
|
} else if c.ACLToken != "" {
|
||||||
|
return c.ACLToken
|
||||||
|
} else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
20
consul/config_test.go
Normal file
20
consul/config_test.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package consul
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestConfig_GetTokenForAgent(t *testing.T) {
|
||||||
|
config := DefaultConfig()
|
||||||
|
if token := config.GetTokenForAgent(); token != "" {
|
||||||
|
t.Fatalf("bad: %s", token)
|
||||||
|
}
|
||||||
|
config.ACLToken = "hello"
|
||||||
|
if token := config.GetTokenForAgent(); token != "hello" {
|
||||||
|
t.Fatalf("bad: %s", token)
|
||||||
|
}
|
||||||
|
config.ACLAgentToken = "world"
|
||||||
|
if token := config.GetTokenForAgent(); token != "world" {
|
||||||
|
t.Fatalf("bad: %s", token)
|
||||||
|
}
|
||||||
|
}
|
@ -428,7 +428,7 @@ AFTER_CHECK:
|
|||||||
Status: structs.HealthPassing,
|
Status: structs.HealthPassing,
|
||||||
Output: SerfCheckAliveOutput,
|
Output: SerfCheckAliveOutput,
|
||||||
},
|
},
|
||||||
WriteRequest: structs.WriteRequest{Token: s.config.ACLToken},
|
WriteRequest: structs.WriteRequest{Token: s.config.GetTokenForAgent()},
|
||||||
}
|
}
|
||||||
var out struct{}
|
var out struct{}
|
||||||
return s.endpoints.Catalog.Register(&req, &out)
|
return s.endpoints.Catalog.Register(&req, &out)
|
||||||
@ -469,7 +469,7 @@ func (s *Server) handleFailedMember(member serf.Member) error {
|
|||||||
Status: structs.HealthCritical,
|
Status: structs.HealthCritical,
|
||||||
Output: SerfCheckFailedOutput,
|
Output: SerfCheckFailedOutput,
|
||||||
},
|
},
|
||||||
WriteRequest: structs.WriteRequest{Token: s.config.ACLToken},
|
WriteRequest: structs.WriteRequest{Token: s.config.GetTokenForAgent()},
|
||||||
}
|
}
|
||||||
var out struct{}
|
var out struct{}
|
||||||
return s.endpoints.Catalog.Register(&req, &out)
|
return s.endpoints.Catalog.Register(&req, &out)
|
||||||
@ -612,7 +612,7 @@ func (s *Server) reapTombstones(index uint64) {
|
|||||||
Datacenter: s.config.Datacenter,
|
Datacenter: s.config.Datacenter,
|
||||||
Op: structs.TombstoneReap,
|
Op: structs.TombstoneReap,
|
||||||
ReapIndex: index,
|
ReapIndex: index,
|
||||||
WriteRequest: structs.WriteRequest{Token: s.config.ACLToken},
|
WriteRequest: structs.WriteRequest{Token: s.config.GetTokenForAgent()},
|
||||||
}
|
}
|
||||||
_, err := s.raftApply(structs.TombstoneRequestType, &req)
|
_, err := s.raftApply(structs.TombstoneRequestType, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -377,6 +377,14 @@ Consul will not enable TLS for the HTTP API unless the `https` port has been ass
|
|||||||
all operations, and "extend-cache" allows any cached ACLs to be used, ignoring their TTL
|
all operations, and "extend-cache" allows any cached ACLs to be used, ignoring their TTL
|
||||||
values. If a non-cached ACL is used, "extend-cache" acts like "deny".
|
values. If a non-cached ACL is used, "extend-cache" acts like "deny".
|
||||||
|
|
||||||
|
* <a name"acl_agent_token"></a><a href="#acl_agent_token">`acl_agent_token`</a> - Used for clients
|
||||||
|
and servers to perform internal operations to the service catalog. If this isn't specified, then
|
||||||
|
the <a href="#acl_token">`acl_token`</a> will be used. This was added in Consul 0.7.2.
|
||||||
|
<br><br>
|
||||||
|
For clients, this token must at least have write access to the node name it will register as. For
|
||||||
|
servers, this must have write access to all nodes that are expected to join the cluster, as well
|
||||||
|
as write access to the "consul" service, which will be registered automatically on its behalf.
|
||||||
|
|
||||||
* <a name="acl_enforce_version_8"></a><a href="#acl_enforce_version_8">`acl_enforce_version_8`</a> -
|
* <a name="acl_enforce_version_8"></a><a href="#acl_enforce_version_8">`acl_enforce_version_8`</a> -
|
||||||
Used for clients and servers to determine if enforcement should occur for new ACL policies being
|
Used for clients and servers to determine if enforcement should occur for new ACL policies being
|
||||||
previewed before Consul 0.8. Added in Consul 0.7.2, this will default to false in versions of
|
previewed before Consul 0.8. Added in Consul 0.7.2, this will default to false in versions of
|
||||||
|
Loading…
x
Reference in New Issue
Block a user