From a8063457f85efe2b70b9f5df5ce08672ad14c717 Mon Sep 17 00:00:00 2001 From: Armon Dadgar Date: Tue, 5 Aug 2014 15:20:35 -0700 Subject: [PATCH] consul: ACL setting passthrough --- command/agent/agent.go | 15 +++++++++++ command/agent/config_test.go | 4 +-- consul/client.go | 5 ++++ consul/config.go | 48 ++++++++++++++++++++++++++++++++++++ consul/server.go | 5 ++++ 5 files changed, 75 insertions(+), 2 deletions(-) diff --git a/command/agent/agent.go b/command/agent/agent.go index 0d8cecfdf8..fdc5536783 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -181,6 +181,21 @@ func (a *Agent) consulConfig() *consul.Config { if a.config.Protocol > 0 { base.ProtocolVersion = uint8(a.config.Protocol) } + if a.config.ACLToken != "" { + base.ACLToken = a.config.ACLToken + } + if a.config.ACLDatacenter != "" { + base.ACLDatacenter = a.config.ACLDatacenter + } + if a.config.ACLTTLRaw != "" { + base.ACLTTL = a.config.ACLTTL + } + if a.config.ACLDefaultPolicy != "" { + base.ACLDefaultPolicy = a.config.ACLDefaultPolicy + } + if a.config.ACLDownPolicy != "" { + base.ACLDownPolicy = a.config.ACLDownPolicy + } // Format the build string revision := a.config.Revision diff --git a/command/agent/config_test.go b/command/agent/config_test.go index c543e87005..973964dcd5 100644 --- a/command/agent/config_test.go +++ b/command/agent/config_test.go @@ -359,7 +359,7 @@ func TestDecodeConfig(t *testing.T) { // ACLs input = `{"acl_token": "1234", "acl_datacenter": "dc2", - "acl_cache_interval": "60s", "acl_down_policy": "deny", + "acl_ttl": "60s", "acl_down_policy": "deny", "acl_default_policy": "deny"}` config, err = DecodeConfig(bytes.NewReader([]byte(input))) if err != nil { @@ -372,7 +372,7 @@ func TestDecodeConfig(t *testing.T) { if config.ACLDatacenter != "dc2" { t.Fatalf("bad: %#v", config) } - if config.ACLCacheInterval != 60*time.Second { + if config.ACLTTL != 60*time.Second { t.Fatalf("bad: %#v", config) } if config.ACLDownPolicy != "deny" { diff --git a/consul/client.go b/consul/client.go index 92d9231959..70626d2de2 100644 --- a/consul/client.go +++ b/consul/client.go @@ -80,6 +80,11 @@ func NewClient(config *Config) (*Client, error) { return nil, fmt.Errorf("Config must provide a DataDir") } + // Sanity check the ACLs + if err := config.CheckACL(); err != nil { + return nil, err + } + // Ensure we have a log output if config.LogOutput == nil { config.LogOutput = os.Stderr diff --git a/consul/config.go b/consul/config.go index 8105e2e24d..92605b33ba 100644 --- a/consul/config.go +++ b/consul/config.go @@ -128,6 +128,33 @@ type Config struct { // operators track which versions are actively deployed Build string + // ACLToken is the default token to use when making a request. + // If not provided, the anonymous token is used. This enables + // backwards compatibility as well. + ACLToken string + + // ACLDatacenter provides the authoritative datacenter for ACL + // tokens. If not provided, ACL verification is disabled. + ACLDatacenter string + + // ACLTTL controls the time-to-live of cached ACL policies. + // It can be set to zero to disable caching, but this adds + // a substantial cost. + ACLTTL time.Duration + + // ACLDefaultPolicy is used to control the ACL interaction when + // there is no defined policy. This can be "allow" which means + // ACLs are used to black-list, or "deny" which means ACLs are + // white-lists. + ACLDefaultPolicy string + + // ACLDownPolicy controls the behavior of ACLs if the ACLDatacenter + // cannot be contacted. It can be either "deny" to deny all requests, + // or "extend-cache" which ignores the ACLCacheInterval and uses + // cached policies. If a policy is not in the cache, it acts like deny. + // "allow" can be used to allow all requests. This is not recommended. + ACLDownPolicy string + // ServerUp callback can be used to trigger a notification that // a Consul server is now up and known about. ServerUp func() @@ -145,6 +172,24 @@ func (c *Config) CheckVersion() error { return nil } +// CheckACL is used to sanity check the ACL configuration +func (c *Config) CheckACL() error { + switch c.ACLDefaultPolicy { + case "allow": + case "deny": + default: + return fmt.Errorf("Unsupported default ACL policy: %s", c.ACLDefaultPolicy) + } + switch c.ACLDownPolicy { + case "allow": + case "deny": + case "extend-cache": + default: + return fmt.Errorf("Unsupported down ACL policy: %s", c.ACLDownPolicy) + } + return nil +} + // AppendCA opens and parses the CA file and adds the certificates to // the provided CertPool. func (c *Config) AppendCA(pool *x509.CertPool) error { @@ -324,6 +369,9 @@ func DefaultConfig() *Config { SerfWANConfig: serf.DefaultConfig(), ReconcileInterval: 60 * time.Second, ProtocolVersion: ProtocolVersionMax, + ACLTTL: 30 * time.Second, + ACLDefaultPolicy: "allow", + ACLDownPolicy: "extend-cache", } // Increase our reap interval to 3 days instead of 24h. diff --git a/consul/server.go b/consul/server.go index af61dc94c7..927b7a74d9 100644 --- a/consul/server.go +++ b/consul/server.go @@ -140,6 +140,11 @@ func NewServer(config *Config) (*Server, error) { return nil, fmt.Errorf("Config must provide a DataDir") } + // Sanity check the ACLs + if err := config.CheckACL(); err != nil { + return nil, err + } + // Ensure we have a log output if config.LogOutput == nil { config.LogOutput = os.Stderr