acl: remove the deprecated `acl_enforce_version_8` option (#7991)

Fixes #7292
pull/7997/head
R.B. Boyer 2020-05-29 16:16:03 -05:00 committed by GitHub
parent c554ba9e10
commit ffb9c7d6f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 683 additions and 1198 deletions

View File

@ -25,11 +25,6 @@ func (a *Agent) resolveTokenAndDefaultMeta(id string, entMeta *structs.Enterpris
return nil, nil return nil, nil
} }
// Disable ACLs if version 8 enforcement isn't enabled.
if !a.config.ACLEnforceVersion8 {
return nil, nil
}
if acl.RootAuthorizer(id) != nil { if acl.RootAuthorizer(id) != nil {
return nil, acl.ErrRootDenied return nil, acl.ErrRootDenied
} }

View File

@ -181,33 +181,19 @@ func (a *TestACLAgent) ReloadConfig(config *consul.Config) error {
return fmt.Errorf("Unimplemented") return fmt.Errorf("Unimplemented")
} }
func TestACL_Version8(t *testing.T) { func TestACL_Version8EnabledByDefault(t *testing.T) {
t.Parallel() t.Parallel()
t.Run("version 8 disabled", func(t *testing.T) { called := false
a := NewTestACLAgent(t, t.Name(), TestACLConfig()+` resolveFn := func(string) (structs.ACLIdentity, acl.Authorizer, error) {
acl_enforce_version_8 = false called = true
`, nil, nil) return nil, nil, acl.ErrNotFound
}
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), resolveFn, nil)
token, err := a.resolveToken("nope") _, err := a.resolveToken("nope")
require.Nil(t, token) require.Error(t, err)
require.Nil(t, err) require.True(t, called)
})
t.Run("version 8 enabled", func(t *testing.T) {
called := false
resolveFn := func(string) (structs.ACLIdentity, acl.Authorizer, error) {
called = true
return nil, nil, acl.ErrNotFound
}
a := NewTestACLAgent(t, t.Name(), TestACLConfig()+`
acl_enforce_version_8 = true
`, resolveFn, nil)
_, err := a.resolveToken("nope")
require.Error(t, err)
require.True(t, called)
})
} }
func TestACL_AgentMasterToken(t *testing.T) { func TestACL_AgentMasterToken(t *testing.T) {

View File

@ -1278,7 +1278,6 @@ func (a *Agent) consulConfig() (*consul.Config, error) {
if a.config.ACLDownPolicy != "" { if a.config.ACLDownPolicy != "" {
base.ACLDownPolicy = a.config.ACLDownPolicy base.ACLDownPolicy = a.config.ACLDownPolicy
} }
base.ACLEnforceVersion8 = a.config.ACLEnforceVersion8
base.ACLTokenReplication = a.config.ACLTokenReplication base.ACLTokenReplication = a.config.ACLTokenReplication
base.ACLsEnabled = a.config.ACLsEnabled base.ACLsEnabled = a.config.ACLsEnabled
if a.config.ACLEnableKeyListPolicy { if a.config.ACLEnableKeyListPolicy {

View File

@ -1307,7 +1307,6 @@ func TestAgent_Reload(t *testing.T) {
t.Parallel() t.Parallel()
dc1 := "dc1" dc1 := "dc1"
a := NewTestAgent(t, ` a := NewTestAgent(t, `
acl_enforce_version_8 = false
services = [ services = [
{ {
name = "redis" name = "redis"
@ -1341,7 +1340,6 @@ func TestAgent_Reload(t *testing.T) {
node_id = "` + string(a.Config.NodeID) + `" node_id = "` + string(a.Config.NodeID) + `"
node_name = "` + a.Config.NodeName + `" node_name = "` + a.Config.NodeName + `"
acl_enforce_version_8 = false
services = [ services = [
{ {
name = "redis-reloaded" name = "redis-reloaded"
@ -1387,7 +1385,6 @@ func TestAgent_ReloadDoesNotTriggerWatch(t *testing.T) {
handlerShell := fmt.Sprintf("(cat ; echo CONSUL_INDEX $CONSUL_INDEX) | tee '%s.atomic' ; mv '%s.atomic' '%s'", tmpFile, tmpFile, tmpFile) handlerShell := fmt.Sprintf("(cat ; echo CONSUL_INDEX $CONSUL_INDEX) | tee '%s.atomic' ; mv '%s.atomic' '%s'", tmpFile, tmpFile, tmpFile)
a := NewTestAgent(t, ` a := NewTestAgent(t, `
acl_enforce_version_8 = false
services = [ services = [
{ {
name = "redis" name = "redis"
@ -1477,7 +1474,6 @@ func TestAgent_ReloadDoesNotTriggerWatch(t *testing.T) {
node_id = "` + string(a.Config.NodeID) + `" node_id = "` + string(a.Config.NodeID) + `"
node_name = "` + a.Config.NodeName + `" node_name = "` + a.Config.NodeName + `"
acl_enforce_version_8 = false
services = [ services = [
{ {
name = "redis" name = "redis"
@ -6031,7 +6027,6 @@ func TestAgentConnectAuthorize_defaultAllow(t *testing.T) {
acl_master_token = "root" acl_master_token = "root"
acl_agent_token = "root" acl_agent_token = "root"
acl_agent_master_token = "towel" acl_agent_master_token = "towel"
acl_enforce_version_8 = true
`) `)
defer a.Shutdown() defer a.Shutdown()
testrpc.WaitForTestAgent(t, a.RPC, dc1) testrpc.WaitForTestAgent(t, a.RPC, dc1)
@ -6063,7 +6058,6 @@ func TestAgent_Host(t *testing.T) {
acl_master_token = "master" acl_master_token = "master"
acl_agent_token = "agent" acl_agent_token = "agent"
acl_agent_master_token = "towel" acl_agent_master_token = "towel"
acl_enforce_version_8 = true
`) `)
defer a.Shutdown() defer a.Shutdown()
@ -6091,7 +6085,6 @@ func TestAgent_HostBadACL(t *testing.T) {
acl_master_token = "root" acl_master_token = "root"
acl_agent_token = "agent" acl_agent_token = "agent"
acl_agent_master_token = "towel" acl_agent_master_token = "towel"
acl_enforce_version_8 = true
`) `)
defer a.Shutdown() defer a.Shutdown()

View File

@ -279,13 +279,26 @@ func (b *Builder) Build() (rt RuntimeConfig, err error) {
if s.Name == "" || s.Data == "" { if s.Name == "" || s.Data == "" {
continue continue
} }
c2, keys, err := Parse(s.Data, s.Format) c2, md, err := Parse(s.Data, s.Format)
if err != nil { if err != nil {
return RuntimeConfig{}, fmt.Errorf("Error parsing %s: %s", s.Name, err) return RuntimeConfig{}, fmt.Errorf("Error parsing %s: %s", s.Name, err)
} }
var unusedErr error
for _, k := range md.Unused {
switch k {
case "acl_enforce_version_8":
b.warn("config key %q is deprecated and should be removed", k)
default:
unusedErr = multierror.Append(unusedErr, fmt.Errorf("invalid config key %s", k))
}
}
if unusedErr != nil {
return RuntimeConfig{}, fmt.Errorf("Error parsing %s: %s", s.Name, unusedErr)
}
// for now this is a soft failure that will cause warnings but not actual problems // for now this is a soft failure that will cause warnings but not actual problems
b.validateEnterpriseConfigKeys(&c2, keys) b.validateEnterpriseConfigKeys(&c2, md.Keys)
// if we have a single 'check' or 'service' we need to add them to the // if we have a single 'check' or 'service' we need to add them to the
// list of checks and services first since we cannot merge them // list of checks and services first since we cannot merge them
@ -790,7 +803,6 @@ func (b *Builder) Build() (rt RuntimeConfig, err error) {
GossipWANRetransmitMult: b.intVal(c.GossipWAN.RetransmitMult), GossipWANRetransmitMult: b.intVal(c.GossipWAN.RetransmitMult),
// ACL // ACL
ACLEnforceVersion8: b.boolValWithDefault(c.ACLEnforceVersion8, true),
ACLsEnabled: aclsEnabled, ACLsEnabled: aclsEnabled,
ACLAgentMasterToken: b.stringValWithDefault(c.ACL.Tokens.AgentMaster, b.stringVal(c.ACLAgentMasterToken)), ACLAgentMasterToken: b.stringValWithDefault(c.ACL.Tokens.AgentMaster, b.stringVal(c.ACLAgentMasterToken)),
ACLAgentToken: b.stringValWithDefault(c.ACL.Tokens.Agent, b.stringVal(c.ACLAgentToken)), ACLAgentToken: b.stringValWithDefault(c.ACL.Tokens.Agent, b.stringVal(c.ACLAgentToken)),

View File

@ -7,7 +7,6 @@ import (
"github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/lib/decode" "github.com/hashicorp/consul/lib/decode"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/hcl" "github.com/hashicorp/hcl"
"github.com/mitchellh/mapstructure" "github.com/mitchellh/mapstructure"
) )
@ -35,7 +34,7 @@ func FormatFrom(name string) string {
} }
// Parse parses a config fragment in either JSON or HCL format. // Parse parses a config fragment in either JSON or HCL format.
func Parse(data string, format string) (c Config, keys []string, err error) { func Parse(data string, format string) (c Config, md mapstructure.Metadata, err error) {
var raw map[string]interface{} var raw map[string]interface{}
switch format { switch format {
case "json": case "json":
@ -46,7 +45,7 @@ func Parse(data string, format string) (c Config, keys []string, err error) {
err = fmt.Errorf("invalid format: %s", format) err = fmt.Errorf("invalid format: %s", format)
} }
if err != nil { if err != nil {
return Config{}, nil, err return Config{}, mapstructure.Metadata{}, err
} }
// We want to be able to report fields which we cannot map as an // We want to be able to report fields which we cannot map as an
@ -109,28 +108,19 @@ func Parse(data string, format string) (c Config, keys []string, err error) {
"config_entries.bootstrap", // completely ignore this tree (fixed elsewhere) "config_entries.bootstrap", // completely ignore this tree (fixed elsewhere)
}) })
var md mapstructure.Metadata
d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
DecodeHook: decode.HookTranslateKeys, DecodeHook: decode.HookTranslateKeys,
Metadata: &md, Metadata: &md,
Result: &c, Result: &c,
}) })
if err != nil { if err != nil {
return Config{}, nil, err return Config{}, mapstructure.Metadata{}, err
} }
if err := d.Decode(m); err != nil { if err := d.Decode(m); err != nil {
return Config{}, nil, err return Config{}, mapstructure.Metadata{}, err
} }
for _, k := range md.Unused { return c, md, nil
err = multierror.Append(err, fmt.Errorf("invalid config key %s", k))
}
// Don't check these here. The builder can emit warnings for fields it
// doesn't like
keys = md.Keys
return
} }
// Config defines the format of a configuration file in either JSON or // Config defines the format of a configuration file in either JSON or
@ -155,8 +145,6 @@ type Config struct {
ACLDownPolicy *string `json:"acl_down_policy,omitempty" hcl:"acl_down_policy" mapstructure:"acl_down_policy"` ACLDownPolicy *string `json:"acl_down_policy,omitempty" hcl:"acl_down_policy" mapstructure:"acl_down_policy"`
// DEPRECATED (ACL-Legacy-Compat) - moved into the "acl" stanza // DEPRECATED (ACL-Legacy-Compat) - moved into the "acl" stanza
ACLEnableKeyListPolicy *bool `json:"acl_enable_key_list_policy,omitempty" hcl:"acl_enable_key_list_policy" mapstructure:"acl_enable_key_list_policy"` ACLEnableKeyListPolicy *bool `json:"acl_enable_key_list_policy,omitempty" hcl:"acl_enable_key_list_policy" mapstructure:"acl_enable_key_list_policy"`
// DEPRECATED (ACL-Legacy-Compat) - pre-version8 enforcement is deprecated.
ACLEnforceVersion8 *bool `json:"acl_enforce_version_8,omitempty" hcl:"acl_enforce_version_8" mapstructure:"acl_enforce_version_8"`
// DEPRECATED (ACL-Legacy-Compat) - moved into the "acl" stanza // DEPRECATED (ACL-Legacy-Compat) - moved into the "acl" stanza
ACLMasterToken *string `json:"acl_master_token,omitempty" hcl:"acl_master_token" mapstructure:"acl_master_token"` ACLMasterToken *string `json:"acl_master_token,omitempty" hcl:"acl_master_token" mapstructure:"acl_master_token"`
// DEPRECATED (ACL-Legacy-Compat) - moved into the "acl.tokens" stanza // DEPRECATED (ACL-Legacy-Compat) - moved into the "acl.tokens" stanza

View File

@ -10,18 +10,6 @@ import (
"github.com/hashicorp/raft" "github.com/hashicorp/raft"
) )
func DefaultRPCProtocol() (int, error) {
src := DefaultSource()
c, _, err := Parse(src.Data, src.Format)
if err != nil {
return 0, fmt.Errorf("Error parsing default config: %s", err)
}
if c.RPCProtocol == nil {
return 0, fmt.Errorf("No default RPC protocol set")
}
return *c.RPCProtocol, nil
}
// DefaultSource is the default agent configuration. // DefaultSource is the default agent configuration.
// This needs to be merged first in the head. // This needs to be merged first in the head.
// todo(fs): The values are sourced from multiple sources. // todo(fs): The values are sourced from multiple sources.
@ -43,7 +31,6 @@ func DefaultSource() Source {
Data: ` Data: `
acl_default_policy = "allow" acl_default_policy = "allow"
acl_down_policy = "extend-cache" acl_down_policy = "extend-cache"
acl_enforce_version_8 = true
acl_ttl = "30s" acl_ttl = "30s"
acl = { acl = {
policy_ttl = "30s" policy_ttl = "30s"
@ -65,7 +52,7 @@ func DefaultSource() Source {
log_level = "INFO" log_level = "INFO"
max_query_time = "600s" max_query_time = "600s"
primary_gateways_interval = "30s" primary_gateways_interval = "30s"
protocol = 2 protocol = ` + strconv.Itoa(consul.DefaultRPCProtocol) + `
retry_interval = "30s" retry_interval = "30s"
retry_interval_wan = "30s" retry_interval_wan = "30s"
server = false server = false

View File

@ -104,13 +104,6 @@ type RuntimeConfig struct {
// hcl: acl.down_policy = ("allow"|"deny"|"extend-cache"|"async-cache") // hcl: acl.down_policy = ("allow"|"deny"|"extend-cache"|"async-cache")
ACLDownPolicy string ACLDownPolicy string
// DEPRECATED (ACL-Legacy-Compat)
// ACLEnforceVersion8 is used to gate a set of ACL policy features that
// are opt-in prior to Consul 0.8 and opt-out in Consul 0.8 and later.
//
// hcl: acl_enforce_version_8 = (true|false)
ACLEnforceVersion8 bool
// ACLEnableKeyListPolicy is used to opt-in to the "list" policy added to // ACLEnableKeyListPolicy is used to opt-in to the "list" policy added to
// KV ACLs in Consul 1.0. // KV ACLs in Consul 1.0.
// //

View File

@ -1619,6 +1619,16 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
rt.DataDir = dataDir rt.DataDir = dataDir
}, },
}, },
{
desc: "acl_enforce_version_8 is deprecated",
args: []string{`-data-dir=` + dataDir},
json: []string{`{ "acl_enforce_version_8": true }`},
hcl: []string{`acl_enforce_version_8 = true`},
patch: func(rt *RuntimeConfig) {
rt.DataDir = dataDir
},
warns: []string{`config key "acl_enforce_version_8" is deprecated and should be removed`},
},
{ {
desc: "advertise address detect fails v4", desc: "advertise address detect fails v4",
args: []string{`-data-dir=` + dataDir}, args: []string{`-data-dir=` + dataDir},
@ -3934,7 +3944,6 @@ func TestFullConfig(t *testing.T) {
"acl_datacenter": "m3urck3z", "acl_datacenter": "m3urck3z",
"acl_default_policy": "ArK3WIfE", "acl_default_policy": "ArK3WIfE",
"acl_down_policy": "vZXMfMP0", "acl_down_policy": "vZXMfMP0",
"acl_enforce_version_8": true,
"acl_enable_key_list_policy": true, "acl_enable_key_list_policy": true,
"acl_master_token": "C1Q1oIwh", "acl_master_token": "C1Q1oIwh",
"acl_replication_token": "LMmgy5dO", "acl_replication_token": "LMmgy5dO",
@ -4570,7 +4579,6 @@ func TestFullConfig(t *testing.T) {
acl_datacenter = "m3urck3z" acl_datacenter = "m3urck3z"
acl_default_policy = "ArK3WIfE" acl_default_policy = "ArK3WIfE"
acl_down_policy = "vZXMfMP0" acl_down_policy = "vZXMfMP0"
acl_enforce_version_8 = true
acl_enable_key_list_policy = true acl_enable_key_list_policy = true
acl_master_token = "C1Q1oIwh" acl_master_token = "C1Q1oIwh"
acl_replication_token = "LMmgy5dO" acl_replication_token = "LMmgy5dO"
@ -5332,7 +5340,6 @@ func TestFullConfig(t *testing.T) {
ACLDatacenter: "ejtmd43d", ACLDatacenter: "ejtmd43d",
ACLDefaultPolicy: "72c2e7a0", ACLDefaultPolicy: "72c2e7a0",
ACLDownPolicy: "03eb2aee", ACLDownPolicy: "03eb2aee",
ACLEnforceVersion8: true,
ACLEnableKeyListPolicy: true, ACLEnableKeyListPolicy: true,
ACLEnableTokenPersistence: true, ACLEnableTokenPersistence: true,
ACLMasterToken: "8a19ac27", ACLMasterToken: "8a19ac27",
@ -6251,7 +6258,6 @@ func TestSanitize(t *testing.T) {
"ACLDownPolicy": "", "ACLDownPolicy": "",
"ACLEnableKeyListPolicy": false, "ACLEnableKeyListPolicy": false,
"ACLEnableTokenPersistence": false, "ACLEnableTokenPersistence": false,
"ACLEnforceVersion8": false,
"ACLMasterToken": "hidden", "ACLMasterToken": "hidden",
"ACLPolicyTTL": "0s", "ACLPolicyTTL": "0s",
"ACLReplicationToken": "hidden", "ACLReplicationToken": "hidden",

View File

@ -1169,29 +1169,23 @@ func (r *ACLResolver) GetMergedPolicyForToken(token string) (*acl.Policy, error)
// aclFilter is used to filter results from our state store based on ACL rules // aclFilter is used to filter results from our state store based on ACL rules
// configured for the provided token. // configured for the provided token.
type aclFilter struct { type aclFilter struct {
authorizer acl.Authorizer authorizer acl.Authorizer
logger hclog.Logger logger hclog.Logger
enforceVersion8 bool
} }
// newACLFilter constructs a new aclFilter. // newACLFilter constructs a new aclFilter.
func newACLFilter(authorizer acl.Authorizer, logger hclog.Logger, enforceVersion8 bool) *aclFilter { func newACLFilter(authorizer acl.Authorizer, logger hclog.Logger) *aclFilter {
if logger == nil { if logger == nil {
logger = hclog.New(&hclog.LoggerOptions{}) logger = hclog.New(&hclog.LoggerOptions{})
} }
return &aclFilter{ return &aclFilter{
authorizer: authorizer, authorizer: authorizer,
logger: logger, logger: logger,
enforceVersion8: enforceVersion8,
} }
} }
// allowNode is used to determine if a node is accessible for an ACL. // allowNode is used to determine if a node is accessible for an ACL.
func (f *aclFilter) allowNode(node string, ent *acl.AuthorizerContext) bool { func (f *aclFilter) allowNode(node string, ent *acl.AuthorizerContext) bool {
if !f.enforceVersion8 {
return true
}
return f.authorizer.NodeRead(node, ent) == acl.Allow return f.authorizer.NodeRead(node, ent) == acl.Allow
} }
@ -1218,18 +1212,12 @@ func (f *aclFilter) allowService(service string, ent *acl.AuthorizerContext) boo
return true return true
} }
if !f.enforceVersion8 && service == structs.ConsulServiceID {
return true
}
return f.authorizer.ServiceRead(service, ent) == acl.Allow return f.authorizer.ServiceRead(service, ent) == acl.Allow
} }
// allowSession is used to determine if a session for a node is accessible for // allowSession is used to determine if a session for a node is accessible for
// an ACL. // an ACL.
func (f *aclFilter) allowSession(node string, ent *acl.AuthorizerContext) bool { func (f *aclFilter) allowSession(node string, ent *acl.AuthorizerContext) bool {
if !f.enforceVersion8 {
return true
}
return f.authorizer.SessionRead(node, ent) == acl.Allow return f.authorizer.SessionRead(node, ent) == acl.Allow
} }
@ -1793,7 +1781,7 @@ func (r *ACLResolver) filterACLWithAuthorizer(authorizer acl.Authorizer, subj in
return nil return nil
} }
// Create the filter // Create the filter
filt := newACLFilter(authorizer, r.logger, r.config.ACLEnforceVersion8) filt := newACLFilter(authorizer, r.logger)
switch v := subj.(type) { switch v := subj.(type) {
case *structs.CheckServiceNodes: case *structs.CheckServiceNodes:

View File

@ -2258,20 +2258,9 @@ func TestACL_filterHealthChecks(t *testing.T) {
} }
} }
// Try permissive filtering.
{ {
hc := fill() hc := fill()
filt := newACLFilter(acl.AllowAll(), nil, false) filt := newACLFilter(acl.DenyAll(), nil)
filt.filterHealthChecks(&hc)
if len(hc) != 1 {
t.Fatalf("bad: %#v", hc)
}
}
// Try restrictive filtering.
{
hc := fill()
filt := newACLFilter(acl.DenyAll(), nil, false)
filt.filterHealthChecks(&hc) filt.filterHealthChecks(&hc)
if len(hc) != 0 { if len(hc) != 0 {
t.Fatalf("bad: %#v", hc) t.Fatalf("bad: %#v", hc)
@ -2292,20 +2281,9 @@ service "foo" {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// This will work because version 8 ACLs aren't being enforced.
{ {
hc := fill() hc := fill()
filt := newACLFilter(perms, nil, false) filt := newACLFilter(perms, nil)
filt.filterHealthChecks(&hc)
if len(hc) != 1 {
t.Fatalf("bad: %#v", hc)
}
}
// But with version 8 the node will block it.
{
hc := fill()
filt := newACLFilter(perms, nil, true)
filt.filterHealthChecks(&hc) filt.filterHealthChecks(&hc)
if len(hc) != 0 { if len(hc) != 0 {
t.Fatalf("bad: %#v", hc) t.Fatalf("bad: %#v", hc)
@ -2329,7 +2307,7 @@ node "node1" {
// Now it should go through. // Now it should go through.
{ {
hc := fill() hc := fill()
filt := newACLFilter(perms, nil, true) filt := newACLFilter(perms, nil)
filt.filterHealthChecks(&hc) filt.filterHealthChecks(&hc)
if len(hc) != 1 { if len(hc) != 1 {
t.Fatalf("bad: %#v", hc) t.Fatalf("bad: %#v", hc)
@ -2357,7 +2335,7 @@ func TestACL_filterIntentions(t *testing.T) {
// Try permissive filtering. // Try permissive filtering.
{ {
ixns := fill() ixns := fill()
filt := newACLFilter(acl.AllowAll(), nil, false) filt := newACLFilter(acl.AllowAll(), nil)
filt.filterIntentions(&ixns) filt.filterIntentions(&ixns)
assert.Len(ixns, 2) assert.Len(ixns, 2)
} }
@ -2365,7 +2343,7 @@ func TestACL_filterIntentions(t *testing.T) {
// Try restrictive filtering. // Try restrictive filtering.
{ {
ixns := fill() ixns := fill()
filt := newACLFilter(acl.DenyAll(), nil, false) filt := newACLFilter(acl.DenyAll(), nil)
filt.filterIntentions(&ixns) filt.filterIntentions(&ixns)
assert.Len(ixns, 0) assert.Len(ixns, 0)
} }
@ -2383,7 +2361,7 @@ service "foo" {
// Filter // Filter
{ {
ixns := fill() ixns := fill()
filt := newACLFilter(perms, nil, false) filt := newACLFilter(perms, nil)
filt.filterIntentions(&ixns) filt.filterIntentions(&ixns)
assert.Len(ixns, 1) assert.Len(ixns, 1)
} }
@ -2399,24 +2377,14 @@ func TestACL_filterServices(t *testing.T) {
} }
// Try permissive filtering. // Try permissive filtering.
filt := newACLFilter(acl.AllowAll(), nil, false) filt := newACLFilter(acl.AllowAll(), nil)
filt.filterServices(services, nil) filt.filterServices(services, nil)
if len(services) != 3 { if len(services) != 3 {
t.Fatalf("bad: %#v", services) t.Fatalf("bad: %#v", services)
} }
// Try restrictive filtering. // Try restrictive filtering.
filt = newACLFilter(acl.DenyAll(), nil, false) filt = newACLFilter(acl.DenyAll(), nil)
filt.filterServices(services, nil)
if len(services) != 1 {
t.Fatalf("bad: %#v", services)
}
if _, ok := services["consul"]; !ok {
t.Fatalf("bad: %#v", services)
}
// Try restrictive filtering with version 8 enforcement.
filt = newACLFilter(acl.DenyAll(), nil, true)
filt.filterServices(services, nil) filt.filterServices(services, nil)
if len(services) != 0 { if len(services) != 0 {
t.Fatalf("bad: %#v", services) t.Fatalf("bad: %#v", services)
@ -2438,7 +2406,7 @@ func TestACL_filterServiceNodes(t *testing.T) {
// Try permissive filtering. // Try permissive filtering.
{ {
nodes := fill() nodes := fill()
filt := newACLFilter(acl.AllowAll(), nil, false) filt := newACLFilter(acl.AllowAll(), nil)
filt.filterServiceNodes(&nodes) filt.filterServiceNodes(&nodes)
if len(nodes) != 1 { if len(nodes) != 1 {
t.Fatalf("bad: %#v", nodes) t.Fatalf("bad: %#v", nodes)
@ -2448,7 +2416,7 @@ func TestACL_filterServiceNodes(t *testing.T) {
// Try restrictive filtering. // Try restrictive filtering.
{ {
nodes := fill() nodes := fill()
filt := newACLFilter(acl.DenyAll(), nil, false) filt := newACLFilter(acl.DenyAll(), nil)
filt.filterServiceNodes(&nodes) filt.filterServiceNodes(&nodes)
if len(nodes) != 0 { if len(nodes) != 0 {
t.Fatalf("bad: %#v", nodes) t.Fatalf("bad: %#v", nodes)
@ -2469,20 +2437,10 @@ service "foo" {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// This will work because version 8 ACLs aren't being enforced.
{
nodes := fill()
filt := newACLFilter(perms, nil, false)
filt.filterServiceNodes(&nodes)
if len(nodes) != 1 {
t.Fatalf("bad: %#v", nodes)
}
}
// But with version 8 the node will block it. // But with version 8 the node will block it.
{ {
nodes := fill() nodes := fill()
filt := newACLFilter(perms, nil, true) filt := newACLFilter(perms, nil)
filt.filterServiceNodes(&nodes) filt.filterServiceNodes(&nodes)
if len(nodes) != 0 { if len(nodes) != 0 {
t.Fatalf("bad: %#v", nodes) t.Fatalf("bad: %#v", nodes)
@ -2506,7 +2464,7 @@ node "node1" {
// Now it should go through. // Now it should go through.
{ {
nodes := fill() nodes := fill()
filt := newACLFilter(perms, nil, true) filt := newACLFilter(perms, nil)
filt.filterServiceNodes(&nodes) filt.filterServiceNodes(&nodes)
if len(nodes) != 1 { if len(nodes) != 1 {
t.Fatalf("bad: %#v", nodes) t.Fatalf("bad: %#v", nodes)
@ -2534,7 +2492,7 @@ func TestACL_filterNodeServices(t *testing.T) {
// Try nil, which is a possible input. // Try nil, which is a possible input.
{ {
var services *structs.NodeServices var services *structs.NodeServices
filt := newACLFilter(acl.AllowAll(), nil, false) filt := newACLFilter(acl.AllowAll(), nil)
filt.filterNodeServices(&services) filt.filterNodeServices(&services)
if services != nil { if services != nil {
t.Fatalf("bad: %#v", services) t.Fatalf("bad: %#v", services)
@ -2544,7 +2502,7 @@ func TestACL_filterNodeServices(t *testing.T) {
// Try permissive filtering. // Try permissive filtering.
{ {
services := fill() services := fill()
filt := newACLFilter(acl.AllowAll(), nil, false) filt := newACLFilter(acl.AllowAll(), nil)
filt.filterNodeServices(&services) filt.filterNodeServices(&services)
if len(services.Services) != 1 { if len(services.Services) != 1 {
t.Fatalf("bad: %#v", services.Services) t.Fatalf("bad: %#v", services.Services)
@ -2554,10 +2512,10 @@ func TestACL_filterNodeServices(t *testing.T) {
// Try restrictive filtering. // Try restrictive filtering.
{ {
services := fill() services := fill()
filt := newACLFilter(acl.DenyAll(), nil, false) filt := newACLFilter(acl.DenyAll(), nil)
filt.filterNodeServices(&services) filt.filterNodeServices(&services)
if len((*services).Services) != 0 { if services != nil {
t.Fatalf("bad: %#v", (*services).Services) t.Fatalf("bad: %#v", *services)
} }
} }
@ -2575,20 +2533,10 @@ service "foo" {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// This will work because version 8 ACLs aren't being enforced. // Node will block it.
{ {
services := fill() services := fill()
filt := newACLFilter(perms, nil, false) filt := newACLFilter(perms, nil)
filt.filterNodeServices(&services)
if len((*services).Services) != 1 {
t.Fatalf("bad: %#v", (*services).Services)
}
}
// But with version 8 the node will block it.
{
services := fill()
filt := newACLFilter(perms, nil, true)
filt.filterNodeServices(&services) filt.filterNodeServices(&services)
if services != nil { if services != nil {
t.Fatalf("bad: %#v", services) t.Fatalf("bad: %#v", services)
@ -2612,7 +2560,7 @@ node "node1" {
// Now it should go through. // Now it should go through.
{ {
services := fill() services := fill()
filt := newACLFilter(perms, nil, true) filt := newACLFilter(perms, nil)
filt.filterNodeServices(&services) filt.filterNodeServices(&services)
if len((*services).Services) != 1 { if len((*services).Services) != 1 {
t.Fatalf("bad: %#v", (*services).Services) t.Fatalf("bad: %#v", (*services).Services)
@ -2647,7 +2595,7 @@ func TestACL_filterCheckServiceNodes(t *testing.T) {
// Try permissive filtering. // Try permissive filtering.
{ {
nodes := fill() nodes := fill()
filt := newACLFilter(acl.AllowAll(), nil, false) filt := newACLFilter(acl.AllowAll(), nil)
filt.filterCheckServiceNodes(&nodes) filt.filterCheckServiceNodes(&nodes)
if len(nodes) != 1 { if len(nodes) != 1 {
t.Fatalf("bad: %#v", nodes) t.Fatalf("bad: %#v", nodes)
@ -2660,7 +2608,7 @@ func TestACL_filterCheckServiceNodes(t *testing.T) {
// Try restrictive filtering. // Try restrictive filtering.
{ {
nodes := fill() nodes := fill()
filt := newACLFilter(acl.DenyAll(), nil, false) filt := newACLFilter(acl.DenyAll(), nil)
filt.filterCheckServiceNodes(&nodes) filt.filterCheckServiceNodes(&nodes)
if len(nodes) != 0 { if len(nodes) != 0 {
t.Fatalf("bad: %#v", nodes) t.Fatalf("bad: %#v", nodes)
@ -2681,23 +2629,9 @@ service "foo" {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// This will work because version 8 ACLs aren't being enforced.
{ {
nodes := fill() nodes := fill()
filt := newACLFilter(perms, nil, false) filt := newACLFilter(perms, nil)
filt.filterCheckServiceNodes(&nodes)
if len(nodes) != 1 {
t.Fatalf("bad: %#v", nodes)
}
if len(nodes[0].Checks) != 1 {
t.Fatalf("bad: %#v", nodes[0].Checks)
}
}
// But with version 8 the node will block it.
{
nodes := fill()
filt := newACLFilter(perms, nil, true)
filt.filterCheckServiceNodes(&nodes) filt.filterCheckServiceNodes(&nodes)
if len(nodes) != 0 { if len(nodes) != 0 {
t.Fatalf("bad: %#v", nodes) t.Fatalf("bad: %#v", nodes)
@ -2721,7 +2655,7 @@ node "node1" {
// Now it should go through. // Now it should go through.
{ {
nodes := fill() nodes := fill()
filt := newACLFilter(perms, nil, true) filt := newACLFilter(perms, nil)
filt.filterCheckServiceNodes(&nodes) filt.filterCheckServiceNodes(&nodes)
if len(nodes) != 1 { if len(nodes) != 1 {
t.Fatalf("bad: %#v", nodes) t.Fatalf("bad: %#v", nodes)
@ -2747,21 +2681,14 @@ func TestACL_filterCoordinates(t *testing.T) {
} }
// Try permissive filtering. // Try permissive filtering.
filt := newACLFilter(acl.AllowAll(), nil, false) filt := newACLFilter(acl.AllowAll(), nil)
filt.filterCoordinates(&coords) filt.filterCoordinates(&coords)
if len(coords) != 2 { if len(coords) != 2 {
t.Fatalf("bad: %#v", coords) t.Fatalf("bad: %#v", coords)
} }
// Try restrictive filtering without version 8 ACL enforcement. // Try restrictive filtering
filt = newACLFilter(acl.DenyAll(), nil, false) filt = newACLFilter(acl.DenyAll(), nil)
filt.filterCoordinates(&coords)
if len(coords) != 2 {
t.Fatalf("bad: %#v", coords)
}
// Try restrictive filtering with version 8 ACL enforcement.
filt = newACLFilter(acl.DenyAll(), nil, true)
filt.filterCoordinates(&coords) filt.filterCoordinates(&coords)
if len(coords) != 0 { if len(coords) != 0 {
t.Fatalf("bad: %#v", coords) t.Fatalf("bad: %#v", coords)
@ -2781,21 +2708,14 @@ func TestACL_filterSessions(t *testing.T) {
} }
// Try permissive filtering. // Try permissive filtering.
filt := newACLFilter(acl.AllowAll(), nil, true) filt := newACLFilter(acl.AllowAll(), nil)
filt.filterSessions(&sessions) filt.filterSessions(&sessions)
if len(sessions) != 2 { if len(sessions) != 2 {
t.Fatalf("bad: %#v", sessions) t.Fatalf("bad: %#v", sessions)
} }
// Try restrictive filtering but with version 8 enforcement turned off. // Try restrictive filtering
filt = newACLFilter(acl.DenyAll(), nil, false) filt = newACLFilter(acl.DenyAll(), nil)
filt.filterSessions(&sessions)
if len(sessions) != 2 {
t.Fatalf("bad: %#v", sessions)
}
// Try restrictive filtering with version 8 enforcement turned on.
filt = newACLFilter(acl.DenyAll(), nil, true)
filt.filterSessions(&sessions) filt.filterSessions(&sessions)
if len(sessions) != 0 { if len(sessions) != 0 {
t.Fatalf("bad: %#v", sessions) t.Fatalf("bad: %#v", sessions)
@ -2829,7 +2749,7 @@ func TestACL_filterNodeDump(t *testing.T) {
// Try permissive filtering. // Try permissive filtering.
{ {
dump := fill() dump := fill()
filt := newACLFilter(acl.AllowAll(), nil, false) filt := newACLFilter(acl.AllowAll(), nil)
filt.filterNodeDump(&dump) filt.filterNodeDump(&dump)
if len(dump) != 1 { if len(dump) != 1 {
t.Fatalf("bad: %#v", dump) t.Fatalf("bad: %#v", dump)
@ -2845,17 +2765,11 @@ func TestACL_filterNodeDump(t *testing.T) {
// Try restrictive filtering. // Try restrictive filtering.
{ {
dump := fill() dump := fill()
filt := newACLFilter(acl.DenyAll(), nil, false) filt := newACLFilter(acl.DenyAll(), nil)
filt.filterNodeDump(&dump) filt.filterNodeDump(&dump)
if len(dump) != 1 { if len(dump) != 0 {
t.Fatalf("bad: %#v", dump) t.Fatalf("bad: %#v", dump)
} }
if len(dump[0].Services) != 0 {
t.Fatalf("bad: %#v", dump[0].Services)
}
if len(dump[0].Checks) != 0 {
t.Fatalf("bad: %#v", dump[0].Checks)
}
} }
// Allowed to see the service but not the node. // Allowed to see the service but not the node.
@ -2872,26 +2786,10 @@ service "foo" {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// This will work because version 8 ACLs aren't being enforced. // But the node will block it.
{ {
dump := fill() dump := fill()
filt := newACLFilter(perms, nil, false) filt := newACLFilter(perms, nil)
filt.filterNodeDump(&dump)
if len(dump) != 1 {
t.Fatalf("bad: %#v", dump)
}
if len(dump[0].Services) != 1 {
t.Fatalf("bad: %#v", dump[0].Services)
}
if len(dump[0].Checks) != 1 {
t.Fatalf("bad: %#v", dump[0].Checks)
}
}
// But with version 8 the node will block it.
{
dump := fill()
filt := newACLFilter(perms, nil, true)
filt.filterNodeDump(&dump) filt.filterNodeDump(&dump)
if len(dump) != 0 { if len(dump) != 0 {
t.Fatalf("bad: %#v", dump) t.Fatalf("bad: %#v", dump)
@ -2915,7 +2813,7 @@ node "node1" {
// Now it should go through. // Now it should go through.
{ {
dump := fill() dump := fill()
filt := newACLFilter(perms, nil, true) filt := newACLFilter(perms, nil)
filt.filterNodeDump(&dump) filt.filterNodeDump(&dump)
if len(dump) != 1 { if len(dump) != 1 {
t.Fatalf("bad: %#v", dump) t.Fatalf("bad: %#v", dump)
@ -2942,21 +2840,14 @@ func TestACL_filterNodes(t *testing.T) {
} }
// Try permissive filtering. // Try permissive filtering.
filt := newACLFilter(acl.AllowAll(), nil, true) filt := newACLFilter(acl.AllowAll(), nil)
filt.filterNodes(&nodes) filt.filterNodes(&nodes)
if len(nodes) != 2 { if len(nodes) != 2 {
t.Fatalf("bad: %#v", nodes) t.Fatalf("bad: %#v", nodes)
} }
// Try restrictive filtering but with version 8 enforcement turned off. // Try restrictive filtering
filt = newACLFilter(acl.DenyAll(), nil, false) filt = newACLFilter(acl.DenyAll(), nil)
filt.filterNodes(&nodes)
if len(nodes) != 2 {
t.Fatalf("bad: %#v", nodes)
}
// Try restrictive filtering with version 8 enforcement turned on.
filt = newACLFilter(acl.DenyAll(), nil, true)
filt.filterNodes(&nodes) filt.filterNodes(&nodes)
if len(nodes) != 0 { if len(nodes) != 0 {
t.Fatalf("bad: %#v", nodes) t.Fatalf("bad: %#v", nodes)
@ -2995,7 +2886,7 @@ func TestACL_filterDatacenterCheckServiceNodes(t *testing.T) {
// Try permissive filtering. // Try permissive filtering.
{ {
dcNodes := fill(t) dcNodes := fill(t)
filt := newACLFilter(acl.AllowAll(), nil, true) filt := newACLFilter(acl.AllowAll(), nil)
filt.filterDatacenterCheckServiceNodes(&dcNodes) filt.filterDatacenterCheckServiceNodes(&dcNodes)
require.Len(t, dcNodes, 2) require.Len(t, dcNodes, 2)
require.Equal(t, fill(t), dcNodes) require.Equal(t, fill(t), dcNodes)
@ -3004,7 +2895,7 @@ func TestACL_filterDatacenterCheckServiceNodes(t *testing.T) {
// Try restrictive filtering. // Try restrictive filtering.
{ {
dcNodes := fill(t) dcNodes := fill(t)
filt := newACLFilter(acl.DenyAll(), nil, true) filt := newACLFilter(acl.DenyAll(), nil)
filt.filterDatacenterCheckServiceNodes(&dcNodes) filt.filterDatacenterCheckServiceNodes(&dcNodes)
require.Len(t, dcNodes, 0) require.Len(t, dcNodes, 0)
} }
@ -3024,7 +2915,7 @@ func TestACL_filterDatacenterCheckServiceNodes(t *testing.T) {
{ {
dcNodes := fill(t) dcNodes := fill(t)
filt := newACLFilter(perms, nil, true) filt := newACLFilter(perms, nil)
filt.filterDatacenterCheckServiceNodes(&dcNodes) filt.filterDatacenterCheckServiceNodes(&dcNodes)
require.Len(t, dcNodes, 0) require.Len(t, dcNodes, 0)
} }
@ -3039,7 +2930,7 @@ func TestACL_filterDatacenterCheckServiceNodes(t *testing.T) {
{ {
dcNodes := fill(t) dcNodes := fill(t)
filt := newACLFilter(perms, nil, true) filt := newACLFilter(perms, nil)
filt.filterDatacenterCheckServiceNodes(&dcNodes) filt.filterDatacenterCheckServiceNodes(&dcNodes)
require.Len(t, dcNodes, 0) require.Len(t, dcNodes, 0)
} }
@ -3056,7 +2947,7 @@ func TestACL_filterDatacenterCheckServiceNodes(t *testing.T) {
// Now it should go through. // Now it should go through.
{ {
dcNodes := fill(t) dcNodes := fill(t)
filt := newACLFilter(acl.AllowAll(), nil, true) filt := newACLFilter(acl.AllowAll(), nil)
filt.filterDatacenterCheckServiceNodes(&dcNodes) filt.filterDatacenterCheckServiceNodes(&dcNodes)
require.Len(t, dcNodes, 2) require.Len(t, dcNodes, 2)
require.Equal(t, fill(t), dcNodes) require.Equal(t, fill(t), dcNodes)
@ -3077,7 +2968,7 @@ func TestACL_redactPreparedQueryTokens(t *testing.T) {
// Try permissive filtering with a management token. This will allow the // Try permissive filtering with a management token. This will allow the
// embedded token to be seen. // embedded token to be seen.
filt := newACLFilter(acl.ManageAll(), nil, false) filt := newACLFilter(acl.ManageAll(), nil)
filt.redactPreparedQueryTokens(&query) filt.redactPreparedQueryTokens(&query)
if !reflect.DeepEqual(query, expected) { if !reflect.DeepEqual(query, expected) {
t.Fatalf("bad: %#v", &query) t.Fatalf("bad: %#v", &query)
@ -3089,7 +2980,7 @@ func TestACL_redactPreparedQueryTokens(t *testing.T) {
// Now try permissive filtering with a client token, which should cause // Now try permissive filtering with a client token, which should cause
// the embedded token to get redacted. // the embedded token to get redacted.
filt = newACLFilter(acl.AllowAll(), nil, false) filt = newACLFilter(acl.AllowAll(), nil)
filt.redactPreparedQueryTokens(&query) filt.redactPreparedQueryTokens(&query)
expected.Token = redactedToken expected.Token = redactedToken
if !reflect.DeepEqual(query, expected) { if !reflect.DeepEqual(query, expected) {
@ -3190,7 +3081,7 @@ func TestACL_filterPreparedQueries(t *testing.T) {
// Try permissive filtering with a management token. This will allow the // Try permissive filtering with a management token. This will allow the
// embedded token to be seen. // embedded token to be seen.
filt := newACLFilter(acl.ManageAll(), nil, false) filt := newACLFilter(acl.ManageAll(), nil)
filt.filterPreparedQueries(&queries) filt.filterPreparedQueries(&queries)
if !reflect.DeepEqual(queries, expected) { if !reflect.DeepEqual(queries, expected) {
t.Fatalf("bad: %#v", queries) t.Fatalf("bad: %#v", queries)
@ -3203,7 +3094,7 @@ func TestACL_filterPreparedQueries(t *testing.T) {
// Now try permissive filtering with a client token, which should cause // Now try permissive filtering with a client token, which should cause
// the embedded token to get redacted, and the query with no name to get // the embedded token to get redacted, and the query with no name to get
// filtered out. // filtered out.
filt = newACLFilter(acl.AllowAll(), nil, false) filt = newACLFilter(acl.AllowAll(), nil)
filt.filterPreparedQueries(&queries) filt.filterPreparedQueries(&queries)
expected[2].Token = redactedToken expected[2].Token = redactedToken
expected = append(structs.PreparedQueries{}, expected[1], expected[2]) expected = append(structs.PreparedQueries{}, expected[1], expected[2])
@ -3217,7 +3108,7 @@ func TestACL_filterPreparedQueries(t *testing.T) {
} }
// Now try restrictive filtering. // Now try restrictive filtering.
filt = newACLFilter(acl.DenyAll(), nil, false) filt = newACLFilter(acl.DenyAll(), nil)
filt.filterPreparedQueries(&queries) filt.filterPreparedQueries(&queries)
if len(queries) != 0 { if len(queries) != 0 {
t.Fatalf("bad: %#v", queries) t.Fatalf("bad: %#v", queries)

View File

@ -150,7 +150,7 @@ func (c *Catalog) Register(args *structs.RegisterRequest, reply *struct{}) error
} }
// Check the complete register request against the given ACL policy. // Check the complete register request against the given ACL policy.
if authz != nil && c.srv.config.ACLEnforceVersion8 { if authz != nil {
state := c.srv.fsm.State() state := c.srv.fsm.State()
_, ns, err := state.NodeServices(nil, args.Node, entMeta) _, ns, err := state.NodeServices(nil, args.Node, entMeta)
if err != nil { if err != nil {
@ -194,7 +194,7 @@ func (c *Catalog) Deregister(args *structs.DeregisterRequest, reply *struct{}) e
} }
// Check the complete deregister request against the given ACL policy. // Check the complete deregister request against the given ACL policy.
if authz != nil && c.srv.config.ACLEnforceVersion8 { if authz != nil {
state := c.srv.fsm.State() state := c.srv.fsm.State()
var ns *structs.NodeService var ns *structs.NodeService

View File

@ -163,11 +163,10 @@ func TestCatalog_Register_ACLDeny(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
@ -182,6 +181,9 @@ func TestCatalog_Register_ACLDeny(t *testing.T) {
service "foo" { service "foo" {
policy = "write" policy = "write"
} }
node "foo" {
policy = "write"
}
`, `,
}, },
WriteRequest: structs.WriteRequest{Token: "root"}, WriteRequest: structs.WriteRequest{Token: "root"},
@ -218,18 +220,9 @@ service "foo" {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// Try the special case for the "consul" service that allows it no matter // Try the former special case for the "consul" service.
// what with pre-version 8 ACL enforcement.
argR.Service.Service = "consul" argR.Service.Service = "consul"
err = msgpackrpc.CallWithCodec(codec, "Catalog.Register", &argR, &outR) err = msgpackrpc.CallWithCodec(codec, "Catalog.Register", &argR, &outR)
if err != nil {
t.Fatalf("err: %v", err)
}
// Make sure the exception goes away when we turn on version 8 ACL
// enforcement.
s1.config.ACLEnforceVersion8 = true
err = msgpackrpc.CallWithCodec(codec, "Catalog.Register", &argR, &outR)
if !acl.IsErrPermissionDenied(err) { if !acl.IsErrPermissionDenied(err) {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -415,6 +408,9 @@ func TestCatalog_Register_ConnectProxy_ACLDestinationServiceName(t *testing.T) {
service "foo" { service "foo" {
policy = "write" policy = "write"
} }
node "foo" {
policy = "write"
}
`, `,
}, },
WriteRequest: structs.WriteRequest{Token: "root"}, WriteRequest: structs.WriteRequest{Token: "root"},
@ -510,7 +506,6 @@ func TestCatalog_Deregister_ACLDeny(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
@ -570,50 +565,9 @@ service "service" {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// First pass with version 8 ACL enforcement disabled, we should be able // We should be not be able to deregister everything without a token.
// to deregister everything even without a token.
var err error var err error
var out struct{} var out struct{}
err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
&structs.DeregisterRequest{
Datacenter: "dc1",
Node: "node",
CheckID: "service-check"}, &out)
if err != nil {
t.Fatalf("err: %v", err)
}
err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
&structs.DeregisterRequest{
Datacenter: "dc1",
Node: "node",
CheckID: "node-check"}, &out)
if err != nil {
t.Fatalf("err: %v", err)
}
err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
&structs.DeregisterRequest{
Datacenter: "dc1",
Node: "node",
ServiceID: "service"}, &out)
if err != nil {
t.Fatalf("err: %v", err)
}
err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
&structs.DeregisterRequest{
Datacenter: "dc1",
Node: "node"}, &out)
if err != nil {
t.Fatalf("err: %v", err)
}
// Turn on version 8 ACL enforcement and put the catalog entry back.
s1.config.ACLEnforceVersion8 = true
if err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &argR, &outR); err != nil {
t.Fatalf("err: %v", err)
}
// Second pass with version 8 ACL enforcement enabled, these should all
// get rejected.
err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister", err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
&structs.DeregisterRequest{ &structs.DeregisterRequest{
Datacenter: "dc1", Datacenter: "dc1",
@ -646,7 +600,7 @@ service "service" {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// Third pass these should all go through with the token set. // Second pass these should all go through with the token set.
err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister", err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
&structs.DeregisterRequest{ &structs.DeregisterRequest{
Datacenter: "dc1", Datacenter: "dc1",
@ -1237,7 +1191,6 @@ func TestCatalog_ListNodes_ACLFilter(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
@ -1250,22 +1203,10 @@ func TestCatalog_ListNodes_ACLFilter(t *testing.T) {
// existing slice if the incoming one is nil, so it's best to start // existing slice if the incoming one is nil, so it's best to start
// clean each time. // clean each time.
// Prior to version 8, the node policy should be ignored. // The node policy should not be ignored.
args := structs.DCSpecificRequest{ args := structs.DCSpecificRequest{
Datacenter: "dc1", Datacenter: "dc1",
} }
{
reply := structs.IndexedNodes{}
if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &reply); err != nil {
t.Fatalf("err: %v", err)
}
if len(reply.Nodes) != 1 {
t.Fatalf("bad: %v", reply.Nodes)
}
}
// Now turn on version 8 enforcement and try again.
s1.config.ACLEnforceVersion8 = true
{ {
reply := structs.IndexedNodes{} reply := structs.IndexedNodes{}
if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &reply); err != nil { if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &reply); err != nil {
@ -2285,7 +2226,6 @@ func TestCatalog_ListServiceNodes_ConnectDestinationNative(t *testing.T) {
func TestCatalog_ListServiceNodes_ConnectProxy_ACL(t *testing.T) { func TestCatalog_ListServiceNodes_ConnectProxy_ACL(t *testing.T) {
t.Parallel() t.Parallel()
assert := assert.New(t)
dir1, s1 := testServerWithConfig(t, func(c *Config) { dir1, s1 := testServerWithConfig(t, func(c *Config) {
c.ACLDatacenter = "dc1" c.ACLDatacenter = "dc1"
c.ACLsEnabled = true c.ACLsEnabled = true
@ -2310,12 +2250,13 @@ func TestCatalog_ListServiceNodes_ConnectProxy_ACL(t *testing.T) {
service "foo" { service "foo" {
policy = "write" policy = "write"
} }
node "" { policy = "read" }
`, `,
}, },
WriteRequest: structs.WriteRequest{Token: "root"}, WriteRequest: structs.WriteRequest{Token: "root"},
} }
var token string var token string
assert.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &token)) require.NoError(t, msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &token))
{ {
// Register a proxy // Register a proxy
@ -2324,21 +2265,21 @@ service "foo" {
args.Service.Proxy.DestinationServiceName = "bar" args.Service.Proxy.DestinationServiceName = "bar"
args.WriteRequest.Token = "root" args.WriteRequest.Token = "root"
var out struct{} var out struct{}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out)) require.NoError(t, msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out))
// Register a proxy // Register a proxy
args = structs.TestRegisterRequestProxy(t) args = structs.TestRegisterRequestProxy(t)
args.Service.Service = "foo-proxy" args.Service.Service = "foo-proxy"
args.Service.Proxy.DestinationServiceName = "foo" args.Service.Proxy.DestinationServiceName = "foo"
args.WriteRequest.Token = "root" args.WriteRequest.Token = "root"
assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out)) require.NoError(t, msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out))
// Register a proxy // Register a proxy
args = structs.TestRegisterRequestProxy(t) args = structs.TestRegisterRequestProxy(t)
args.Service.Service = "another-proxy" args.Service.Service = "another-proxy"
args.Service.Proxy.DestinationServiceName = "foo" args.Service.Proxy.DestinationServiceName = "foo"
args.WriteRequest.Token = "root" args.WriteRequest.Token = "root"
assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out)) require.NoError(t, msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out))
} }
// List w/ token. This should disallow because we don't have permission // List w/ token. This should disallow because we don't have permission
@ -2350,8 +2291,8 @@ service "foo" {
QueryOptions: structs.QueryOptions{Token: token}, QueryOptions: structs.QueryOptions{Token: token},
} }
var resp structs.IndexedServiceNodes var resp structs.IndexedServiceNodes
assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp)) require.NoError(t, msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
assert.Len(resp.ServiceNodes, 0) require.Len(t, resp.ServiceNodes, 0)
// List w/ token. This should work since we're requesting "foo", but should // List w/ token. This should work since we're requesting "foo", but should
// also only contain the proxies with names that adhere to our ACL. // also only contain the proxies with names that adhere to our ACL.
@ -2361,10 +2302,11 @@ service "foo" {
ServiceName: "foo", ServiceName: "foo",
QueryOptions: structs.QueryOptions{Token: token}, QueryOptions: structs.QueryOptions{Token: token},
} }
assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp)) resp = structs.IndexedServiceNodes{}
assert.Len(resp.ServiceNodes, 1) require.NoError(t, msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
require.Len(t, resp.ServiceNodes, 1)
v := resp.ServiceNodes[0] v := resp.ServiceNodes[0]
assert.Equal("foo-proxy", v.ServiceName) require.Equal(t, "foo-proxy", v.ServiceName)
} }
func TestCatalog_ListServiceNodes_ConnectNative(t *testing.T) { func TestCatalog_ListServiceNodes_ConnectNative(t *testing.T) {
@ -2564,11 +2506,10 @@ func testACLFilterServer(t *testing.T) (dir, token string, srv *Server, codec rp
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
}) })
codec = rpcClient(t, srv) codec = rpcClient(t, srv)
testrpc.WaitForLeader(t, srv.RPC, "dc1") testrpc.WaitForTestAgent(t, srv.RPC, "dc1", testrpc.WithToken("root"))
// Create a new token // Create a new token
arg := structs.ACLRequest{ arg := structs.ACLRequest{
@ -2581,6 +2522,9 @@ func testACLFilterServer(t *testing.T) (dir, token string, srv *Server, codec rp
service "foo" { service "foo" {
policy = "write" policy = "write"
} }
node "" {
policy = "read"
}
`, `,
}, },
WriteRequest: structs.WriteRequest{Token: "root"}, WriteRequest: structs.WriteRequest{Token: "root"},
@ -2638,7 +2582,7 @@ func TestCatalog_ListServices_FilterACL(t *testing.T) {
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
defer srv.Shutdown() defer srv.Shutdown()
defer codec.Close() defer codec.Close()
testrpc.WaitForTestAgent(t, srv.RPC, "dc1") testrpc.WaitForTestAgent(t, srv.RPC, "dc1", testrpc.WithToken("root"))
opt := structs.DCSpecificRequest{ opt := structs.DCSpecificRequest{
Datacenter: "dc1", Datacenter: "dc1",
@ -2713,16 +2657,15 @@ func TestCatalog_NodeServices_ACLDeny(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Prior to version 8, the node policy should be ignored. // The node policy should not be ignored.
args := structs.NodeSpecificRequest{ args := structs.NodeSpecificRequest{
Datacenter: "dc1", Datacenter: "dc1",
Node: s1.config.NodeName, Node: s1.config.NodeName,
@ -2731,15 +2674,6 @@ func TestCatalog_NodeServices_ACLDeny(t *testing.T) {
if err := msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &args, &reply); err != nil { if err := msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &args, &reply); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
if reply.NodeServices == nil {
t.Fatalf("should not be nil")
}
// Now turn on version 8 enforcement and try again.
s1.config.ACLEnforceVersion8 = true
if err := msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &args, &reply); err != nil {
t.Fatalf("err: %v", err)
}
if reply.NodeServices != nil { if reply.NodeServices != nil {
t.Fatalf("should not nil") t.Fatalf("should not nil")
} }
@ -2789,28 +2723,21 @@ func TestCatalog_NodeServices_FilterACL(t *testing.T) {
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
defer srv.Shutdown() defer srv.Shutdown()
defer codec.Close() defer codec.Close()
testrpc.WaitForTestAgent(t, srv.RPC, "dc1") testrpc.WaitForTestAgent(t, srv.RPC, "dc1", testrpc.WithToken("root"))
opt := structs.NodeSpecificRequest{ opt := structs.NodeSpecificRequest{
Datacenter: "dc1", Datacenter: "dc1",
Node: srv.config.NodeName, Node: srv.config.NodeName,
QueryOptions: structs.QueryOptions{Token: token}, QueryOptions: structs.QueryOptions{Token: token},
} }
reply := structs.IndexedNodeServices{}
if err := msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &opt, &reply); err != nil { var reply structs.IndexedNodeServices
t.Fatalf("err: %s", err) require.NoError(t, msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &opt, &reply))
}
found := false require.NotNil(t, reply.NodeServices)
for _, svc := range reply.NodeServices.Services { require.Len(t, reply.NodeServices.Services, 1)
if svc.ID == "bar" {
t.Fatalf("bad: %#v", reply.NodeServices.Services) svc, ok := reply.NodeServices.Services["foo"]
} require.True(t, ok)
if svc.ID == "foo" { require.Equal(t, "foo", svc.ID)
found = true
break
}
}
if !found {
t.Fatalf("bad: %#v", reply.NodeServices)
}
} }

View File

@ -237,10 +237,6 @@ type Config struct {
// ACLEnabled is used to enable ACLs // ACLEnabled is used to enable ACLs
ACLsEnabled bool ACLsEnabled bool
// ACLEnforceVersion8 is used to gate a set of ACL policy features that
// are opt-in prior to Consul 0.8 and opt-out in Consul 0.8 and later.
ACLEnforceVersion8 bool
// 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.

View File

@ -145,7 +145,7 @@ func TestConfigEntry_Apply_ACLDeny(t *testing.T) {
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
@ -266,7 +266,7 @@ func TestConfigEntry_Get_ACLDeny(t *testing.T) {
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
@ -421,7 +421,7 @@ func TestConfigEntry_List_ACLDeny(t *testing.T) {
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
@ -502,7 +502,7 @@ func TestConfigEntry_ListAll_ACLDeny(t *testing.T) {
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
@ -652,7 +652,7 @@ func TestConfigEntry_Delete_ACLDeny(t *testing.T) {
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
@ -1119,7 +1119,7 @@ func TestConfigEntry_ResolveServiceConfig_ACLDeny(t *testing.T) {
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()

View File

@ -143,7 +143,7 @@ func (c *Coordinate) Update(args *structs.CoordinateUpdateRequest, reply *struct
if err != nil { if err != nil {
return err return err
} }
if authz != nil && c.srv.config.ACLEnforceVersion8 { if authz != nil {
var authzContext acl.AuthorizerContext var authzContext acl.AuthorizerContext
structs.DefaultEnterpriseMeta().FillAuthzContext(&authzContext) structs.DefaultEnterpriseMeta().FillAuthzContext(&authzContext)
if authz.NodeWrite(args.Node, &authzContext) != acl.Allow { if authz.NodeWrite(args.Node, &authzContext) != acl.Allow {
@ -217,7 +217,7 @@ func (c *Coordinate) Node(args *structs.NodeSpecificRequest, reply *structs.Inde
if err != nil { if err != nil {
return err return err
} }
if authz != nil && c.srv.config.ACLEnforceVersion8 { if authz != nil {
var authzContext acl.AuthorizerContext var authzContext acl.AuthorizerContext
structs.WildcardEnterpriseMeta().FillAuthzContext(&authzContext) structs.WildcardEnterpriseMeta().FillAuthzContext(&authzContext)
if authz.NodeRead(args.Node, &authzContext) != acl.Allow { if authz.NodeRead(args.Node, &authzContext) != acl.Allow {

View File

@ -15,7 +15,7 @@ import (
"github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/sdk/testutil/retry" "github.com/hashicorp/consul/sdk/testutil/retry"
"github.com/hashicorp/consul/testrpc" "github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/net-rpc-msgpackrpc" msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc"
"github.com/hashicorp/serf/coordinate" "github.com/hashicorp/serf/coordinate"
"github.com/pascaldekloe/goe/verify" "github.com/pascaldekloe/goe/verify"
) )
@ -51,7 +51,7 @@ func TestCoordinate_Update(t *testing.T) {
// Register some nodes. // Register some nodes.
nodes := []string{"node1", "node2"} nodes := []string{"node1", "node2"}
if err := registerNodes(nodes, codec); err != nil { if err := registerNodes(nodes, codec, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -184,22 +184,21 @@ func TestCoordinate_Update_ACLDeny(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1") testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Register some nodes. // Register some nodes.
nodes := []string{"node1", "node2"} nodes := []string{"node1", "node2"}
if err := registerNodes(nodes, codec); err != nil { if err := registerNodes(nodes, codec, "root"); err != nil {
t.Fatal(err) t.Fatal(err)
} }
// Send an update for the first node. This should go through since we // Send an update for the first node.
// don't have version 8 ACLs enforced yet. // don't have version 8 ACLs enforced yet.
req := structs.CoordinateUpdateRequest{ req := structs.CoordinateUpdateRequest{
Datacenter: "dc1", Datacenter: "dc1",
@ -207,12 +206,6 @@ func TestCoordinate_Update_ACLDeny(t *testing.T) {
Coord: generateRandomCoordinate(), Coord: generateRandomCoordinate(),
} }
var out struct{} var out struct{}
if err := msgpackrpc.CallWithCodec(codec, "Coordinate.Update", &req, &out); err != nil {
t.Fatalf("err: %v", err)
}
// Now turn on version 8 enforcement and try again.
s1.config.ACLEnforceVersion8 = true
err := msgpackrpc.CallWithCodec(codec, "Coordinate.Update", &req, &out) err := msgpackrpc.CallWithCodec(codec, "Coordinate.Update", &req, &out)
if !acl.IsErrPermissionDenied(err) { if !acl.IsErrPermissionDenied(err) {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
@ -295,7 +288,7 @@ func TestCoordinate_ListNodes(t *testing.T) {
// Register some nodes. // Register some nodes.
nodes := []string{"foo", "bar", "baz"} nodes := []string{"foo", "bar", "baz"}
if err := registerNodes(nodes, codec); err != nil { if err := registerNodes(nodes, codec, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -355,14 +348,13 @@ func TestCoordinate_ListNodes_ACLFilter(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1") testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Register some nodes. // Register some nodes.
nodes := []string{"foo", "bar", "baz"} nodes := []string{"foo", "bar", "baz"}
@ -418,12 +410,12 @@ func TestCoordinate_ListNodes_ACLFilter(t *testing.T) {
if err := msgpackrpc.CallWithCodec(codec, "Coordinate.Update", &arg3, &out); err != nil { if err := msgpackrpc.CallWithCodec(codec, "Coordinate.Update", &arg3, &out); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// Wait for all the coordinate updates to apply. Since we aren't
// enforcing version 8 ACLs, this should also allow us to read // Wait for all the coordinate updates to apply.
// everything back without a token.
retry.Run(t, func(r *retry.R) { retry.Run(t, func(r *retry.R) {
arg := structs.DCSpecificRequest{ arg := structs.DCSpecificRequest{
Datacenter: "dc1", Datacenter: "dc1",
QueryOptions: structs.QueryOptions{Token: "root"},
} }
resp := structs.IndexedCoordinates{} resp := structs.IndexedCoordinates{}
if err := msgpackrpc.CallWithCodec(codec, "Coordinate.ListNodes", &arg, &resp); err != nil { if err := msgpackrpc.CallWithCodec(codec, "Coordinate.ListNodes", &arg, &resp); err != nil {
@ -435,10 +427,7 @@ func TestCoordinate_ListNodes_ACLFilter(t *testing.T) {
}) })
// Now that we've waited for the batch processing to ingest the // Now that we've waited for the batch processing to ingest the
// coordinates we can do the rest of the requests without the loop. We // coordinates we can do the rest of the requests without the loop.
// will start by turning on version 8 ACL support which should block
// everything.
s1.config.ACLEnforceVersion8 = true
arg := structs.DCSpecificRequest{ arg := structs.DCSpecificRequest{
Datacenter: "dc1", Datacenter: "dc1",
} }
@ -494,7 +483,7 @@ func TestCoordinate_Node(t *testing.T) {
// Register some nodes. // Register some nodes.
nodes := []string{"foo", "bar"} nodes := []string{"foo", "bar"}
if err := registerNodes(nodes, codec); err != nil { if err := registerNodes(nodes, codec, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -543,52 +532,38 @@ func TestCoordinate_Node_ACLDeny(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1") testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Register some nodes. // Register some nodes.
nodes := []string{"node1", "node2"} nodes := []string{"node1", "node2"}
if err := registerNodes(nodes, codec); err != nil { if err := registerNodes(nodes, codec, "root"); err != nil {
t.Fatal(err) t.Fatal(err)
} }
coord := generateRandomCoordinate() coord := generateRandomCoordinate()
req := structs.CoordinateUpdateRequest{ req := structs.CoordinateUpdateRequest{
Datacenter: "dc1", Datacenter: "dc1",
Node: "node1", Node: "node1",
Coord: coord, Coord: coord,
WriteRequest: structs.WriteRequest{Token: "root"},
} }
var out struct{} var out struct{}
if err := msgpackrpc.CallWithCodec(codec, "Coordinate.Update", &req, &out); err != nil { if err := msgpackrpc.CallWithCodec(codec, "Coordinate.Update", &req, &out); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// Try a read for the first node. This should go through since we // Try a read for the first node. This should fail without a token.
// don't have version 8 ACLs enforced yet.
arg := structs.NodeSpecificRequest{ arg := structs.NodeSpecificRequest{
Node: "node1", Node: "node1",
Datacenter: "dc1", Datacenter: "dc1",
} }
resp := structs.IndexedCoordinates{} resp := structs.IndexedCoordinates{}
retry.Run(t, func(r *retry.R) {
if err := msgpackrpc.CallWithCodec(codec, "Coordinate.Node", &arg, &resp); err != nil {
r.Fatalf("err: %v", err)
}
if len(resp.Coordinates) != 1 ||
resp.Coordinates[0].Node != "node1" {
r.Fatalf("bad: %v", resp.Coordinates)
}
verify.Values(t, "", resp.Coordinates[0].Coord, coord)
})
// Now turn on version 8 enforcement and try again.
s1.config.ACLEnforceVersion8 = true
err := msgpackrpc.CallWithCodec(codec, "Coordinate.Node", &arg, &resp) err := msgpackrpc.CallWithCodec(codec, "Coordinate.Node", &arg, &resp)
if !acl.IsErrPermissionDenied(err) { if !acl.IsErrPermissionDenied(err) {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
@ -628,12 +603,13 @@ node "node1" {
} }
} }
func registerNodes(nodes []string, codec rpc.ClientCodec) error { func registerNodes(nodes []string, codec rpc.ClientCodec, token string) error {
for _, node := range nodes { for _, node := range nodes {
req := structs.RegisterRequest{ req := structs.RegisterRequest{
Datacenter: "dc1", Datacenter: "dc1",
Node: node, Node: node,
Address: "127.0.0.1", Address: "127.0.0.1",
WriteRequest: structs.WriteRequest{Token: token},
} }
var reply struct{} var reply struct{}
if err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &req, &reply); err != nil { if err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &req, &reply); err != nil {

View File

@ -29,8 +29,8 @@ func TestDiscoveryChainEndpoint_Get(t *testing.T) {
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") waitForLeaderEstablishment(t, s1)
testrpc.WaitForLeader(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
denyToken, err := upsertTestTokenWithPolicyRules(codec, "root", "dc1", "") denyToken, err := upsertTestTokenWithPolicyRules(codec, "root", "dc1", "")
require.NoError(t, err) require.NoError(t, err)

View File

@ -112,7 +112,7 @@ func TestFederationState_Apply_Upsert_ACLDeny(t *testing.T) {
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
@ -224,7 +224,7 @@ func TestFederationState_Get_ACLDeny(t *testing.T) {
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
@ -383,7 +383,6 @@ func TestFederationState_List_ACLDeny(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true // apparently this is still not defaulted to true in server code
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
@ -400,7 +399,6 @@ func TestFederationState_List_ACLDeny(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true // ugh
}) })
defer os.RemoveAll(dir2) defer os.RemoveAll(dir2)
defer s2.Shutdown() defer s2.Shutdown()

View File

@ -936,14 +936,13 @@ func TestHealth_ServiceNodes_ConnectProxy_ACL(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1") testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create the ACL. // Create the ACL.
arg := structs.ACLRequest{ arg := structs.ACLRequest{
@ -956,6 +955,9 @@ func TestHealth_ServiceNodes_ConnectProxy_ACL(t *testing.T) {
service "foo" { service "foo" {
policy = "write" policy = "write"
} }
node "foo" {
policy = "write"
}
`, `,
}, },
WriteRequest: structs.WriteRequest{Token: "root"}, WriteRequest: structs.WriteRequest{Token: "root"},
@ -1236,14 +1238,13 @@ func TestHealth_ServiceNodes_Ingress_ACL(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1") testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create the ACL. // Create the ACL.
token, err := upsertTestTokenWithPolicyRules(codec, "root", "dc1", ` token, err := upsertTestTokenWithPolicyRules(codec, "root", "dc1", `

View File

@ -967,7 +967,6 @@ func TestInternal_GatewayServices_ACLFiltering(t *testing.T) {
dir1, s1 := testServerWithConfig(t, func(c *Config) { dir1, s1 := testServerWithConfig(t, func(c *Config) {
c.ACLDatacenter = "dc1" c.ACLDatacenter = "dc1"
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLEnforceVersion8 = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
}) })
@ -1355,7 +1354,6 @@ func TestInternal_GatewayServiceDump_Terminating_ACL(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
@ -1691,7 +1689,6 @@ func TestInternal_GatewayServiceDump_Ingress_ACL(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()

View File

@ -9,7 +9,7 @@ import (
"github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/testrpc" "github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/net-rpc-msgpackrpc" msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc"
"github.com/pascaldekloe/goe/verify" "github.com/pascaldekloe/goe/verify"
) )
@ -83,7 +83,7 @@ func TestKVS_Apply_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create the ACL // Create the ACL
arg := structs.ACLRequest{ arg := structs.ACLRequest{
@ -195,7 +195,7 @@ func TestKVS_Get_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
arg := structs.KVSRequest{ arg := structs.KVSRequest{
Datacenter: "dc1", Datacenter: "dc1",
@ -404,7 +404,7 @@ func TestKVSEndpoint_List_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
keys := []string{ keys := []string{
"abe", "abe",
@ -491,7 +491,7 @@ func TestKVSEndpoint_List_ACLEnableKeyListPolicy(t *testing.T) {
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
keys := []string{ keys := []string{
"abe", "abe",
@ -685,7 +685,7 @@ func TestKVSEndpoint_ListKeys_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
keys := []string{ keys := []string{
"abe", "abe",

View File

@ -26,7 +26,6 @@ func TestLeader_RegisterMember(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
@ -98,7 +97,6 @@ func TestLeader_FailedMember(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
@ -160,7 +158,6 @@ func TestLeader_LeftMember(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
@ -207,7 +204,6 @@ func TestLeader_ReapMember(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
@ -269,7 +265,6 @@ func TestLeader_ReapServer(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "allow" c.ACLDefaultPolicy = "allow"
c.ACLEnforceVersion8 = true
c.Bootstrap = true c.Bootstrap = true
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
@ -280,7 +275,6 @@ func TestLeader_ReapServer(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "allow" c.ACLDefaultPolicy = "allow"
c.ACLEnforceVersion8 = true
c.Bootstrap = false c.Bootstrap = false
}) })
defer os.RemoveAll(dir2) defer os.RemoveAll(dir2)
@ -291,7 +285,6 @@ func TestLeader_ReapServer(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "allow" c.ACLDefaultPolicy = "allow"
c.ACLEnforceVersion8 = true
c.Bootstrap = false c.Bootstrap = false
}) })
defer os.RemoveAll(dir3) defer os.RemoveAll(dir3)
@ -347,7 +340,6 @@ func TestLeader_Reconcile_ReapMember(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
@ -397,7 +389,6 @@ func TestLeader_Reconcile(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()

View File

@ -71,7 +71,7 @@ func TestOperator_RaftGetConfiguration_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Make a request with no token to make sure it gets denied. // Make a request with no token to make sure it gets denied.
arg := structs.DCSpecificRequest{ arg := structs.DCSpecificRequest{
@ -211,7 +211,7 @@ func TestOperator_RaftRemovePeerByAddress_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Make a request with no token to make sure it gets denied. // Make a request with no token to make sure it gets denied.
arg := structs.RaftRemovePeerRequest{ arg := structs.RaftRemovePeerRequest{

View File

@ -101,7 +101,7 @@ func (p *PreparedQuery) Apply(args *structs.PreparedQueryRequest, reply *string)
// Parse the query and prep it for the state store. // Parse the query and prep it for the state store.
switch args.Op { switch args.Op {
case structs.PreparedQueryCreate, structs.PreparedQueryUpdate: case structs.PreparedQueryCreate, structs.PreparedQueryUpdate:
if err := parseQuery(args.Query, p.srv.config.ACLEnforceVersion8); err != nil { if err := parseQuery(args.Query); err != nil {
return fmt.Errorf("Invalid prepared query: %v", err) return fmt.Errorf("Invalid prepared query: %v", err)
} }
@ -130,7 +130,7 @@ func (p *PreparedQuery) Apply(args *structs.PreparedQueryRequest, reply *string)
// update operation. Some of the fields are not checked or are partially // update operation. Some of the fields are not checked or are partially
// checked, as noted in the comments below. This also updates all the parsed // checked, as noted in the comments below. This also updates all the parsed
// fields of the query. // fields of the query.
func parseQuery(query *structs.PreparedQuery, enforceVersion8 bool) error { func parseQuery(query *structs.PreparedQuery) error {
// We skip a few fields: // We skip a few fields:
// - ID is checked outside this fn. // - ID is checked outside this fn.
// - Name is optional with no restrictions, except for uniqueness which // - Name is optional with no restrictions, except for uniqueness which
@ -142,10 +142,8 @@ func parseQuery(query *structs.PreparedQuery, enforceVersion8 bool) error {
// compile it. // compile it.
// Anonymous queries require a session or need to be part of a template. // Anonymous queries require a session or need to be part of a template.
if enforceVersion8 { if query.Name == "" && query.Template.Type == "" && query.Session == "" {
if query.Name == "" && query.Template.Type == "" && query.Session == "" { return fmt.Errorf("Must be bound to a session")
return fmt.Errorf("Must be bound to a session")
}
} }
// Token is checked when the query is executed, but we do make sure the // Token is checked when the query is executed, but we do make sure the

File diff suppressed because it is too large Load Diff

View File

@ -743,7 +743,6 @@ func TestRPC_LocalTokenStrippedOnForward(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLEnforceVersion8 = true
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
@ -757,7 +756,6 @@ func TestRPC_LocalTokenStrippedOnForward(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLTokenReplication = true c.ACLTokenReplication = true
c.ACLEnforceVersion8 = true
c.ACLReplicationRate = 100 c.ACLReplicationRate = 100
c.ACLReplicationBurst = 100 c.ACLReplicationBurst = 100
c.ACLReplicationApplyLimit = 1000000 c.ACLReplicationApplyLimit = 1000000

View File

@ -46,6 +46,8 @@ import (
// Consul-level protocol versions, that are used to configure the Serf // Consul-level protocol versions, that are used to configure the Serf
// protocol versions. // protocol versions.
const ( const (
DefaultRPCProtocol = 2
ProtocolVersionMin uint8 = 2 ProtocolVersionMin uint8 = 2
// Version 3 added support for network coordinates but we kept the // Version 3 added support for network coordinates but we kept the

View File

@ -47,7 +47,6 @@ func testServerACLConfig(cb func(*Config)) func(*Config) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = TestDefaultMasterToken c.ACLMasterToken = TestDefaultMasterToken
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
if cb != nil { if cb != nil {
cb(c) cb(c)

View File

@ -59,7 +59,7 @@ func (s *Session) Apply(args *structs.SessionRequest, reply *string) error {
return err return err
} }
if authz != nil && s.srv.config.ACLEnforceVersion8 { if authz != nil {
switch args.Op { switch args.Op {
case structs.SessionDestroy: case structs.SessionDestroy:
state := s.srv.fsm.State() state := s.srv.fsm.State()
@ -302,7 +302,7 @@ func (s *Session) Renew(args *structs.SessionSpecificRequest,
return nil return nil
} }
if authz != nil && s.srv.config.ACLEnforceVersion8 && authz.SessionWrite(session.Node, &authzContext) != acl.Allow { if authz != nil && authz.SessionWrite(session.Node, &authzContext) != acl.Allow {
return acl.ErrPermissionDenied return acl.ErrPermissionDenied
} }

View File

@ -145,7 +145,6 @@ func TestSession_Apply_ACLDeny(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
@ -153,7 +152,7 @@ func TestSession_Apply_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1") testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create the ACL. // Create the ACL.
req := structs.ACLRequest{ req := structs.ACLRequest{
@ -179,8 +178,7 @@ session "foo" {
// Just add a node. // Just add a node.
s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}) s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"})
// Try to create without a token, which will go through since version 8 // Try to create without a token, which will be denied.
// enforcement isn't enabled.
arg := structs.SessionRequest{ arg := structs.SessionRequest{
Datacenter: "dc1", Datacenter: "dc1",
Op: structs.SessionCreate, Op: structs.SessionCreate,
@ -189,40 +187,23 @@ session "foo" {
Name: "my-session", Name: "my-session",
}, },
} }
var id1 string var id string
if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &id1); err != nil { err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &id)
t.Fatalf("err: %v", err)
}
// Now turn on version 8 enforcement and try again, it should be denied.
var id2 string
s1.config.ACLEnforceVersion8 = true
err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &id2)
if !acl.IsErrPermissionDenied(err) { if !acl.IsErrPermissionDenied(err) {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// Now set a token and try again. This should go through. // Now set a token and try again. This should go through.
arg.Token = token arg.Token = token
if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &id2); err != nil { if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// Do a delete on the first session with version 8 enforcement off and // Make sure the delete of the session fails without a token.
// no token. This should go through.
var out string var out string
s1.config.ACLEnforceVersion8 = false
arg.Op = structs.SessionDestroy arg.Op = structs.SessionDestroy
arg.Session.ID = id
arg.Token = "" arg.Token = ""
arg.Session.ID = id1
if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil {
t.Fatalf("err: %v", err)
}
// Turn on version 8 enforcement and make sure the delete of the second
// session fails.
s1.config.ACLEnforceVersion8 = true
arg.Session.ID = id2
err = msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out) err = msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out)
if !acl.IsErrPermissionDenied(err) { if !acl.IsErrPermissionDenied(err) {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
@ -386,7 +367,6 @@ func TestSession_Get_List_NodeSessions_ACLFilter(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
@ -394,7 +374,7 @@ func TestSession_Get_List_NodeSessions_ACLFilter(t *testing.T) {
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1") testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create the ACL. // Create the ACL.
req := structs.ACLRequest{ req := structs.ACLRequest{
@ -432,8 +412,7 @@ session "foo" {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// Perform all the read operations, which should go through since version // Perform all the read operations, and make sure everything is empty.
// 8 ACL enforcement isn't enabled.
getR := structs.SessionSpecificRequest{ getR := structs.SessionSpecificRequest{
Datacenter: "dc1", Datacenter: "dc1",
SessionID: out, SessionID: out,
@ -443,7 +422,7 @@ session "foo" {
if err := msgpackrpc.CallWithCodec(codec, "Session.Get", &getR, &sessions); err != nil { if err := msgpackrpc.CallWithCodec(codec, "Session.Get", &getR, &sessions); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
if len(sessions.Sessions) != 1 { if len(sessions.Sessions) != 0 {
t.Fatalf("bad: %v", sessions.Sessions) t.Fatalf("bad: %v", sessions.Sessions)
} }
} }
@ -452,10 +431,11 @@ session "foo" {
} }
{ {
var sessions structs.IndexedSessions var sessions structs.IndexedSessions
if err := msgpackrpc.CallWithCodec(codec, "Session.List", &listR, &sessions); err != nil { if err := msgpackrpc.CallWithCodec(codec, "Session.List", &listR, &sessions); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
if len(sessions.Sessions) != 1 { if len(sessions.Sessions) != 0 {
t.Fatalf("bad: %v", sessions.Sessions) t.Fatalf("bad: %v", sessions.Sessions)
} }
} }
@ -463,37 +443,6 @@ session "foo" {
Datacenter: "dc1", Datacenter: "dc1",
Node: "foo", Node: "foo",
} }
{
var sessions structs.IndexedSessions
if err := msgpackrpc.CallWithCodec(codec, "Session.NodeSessions", &nodeR, &sessions); err != nil {
t.Fatalf("err: %v", err)
}
if len(sessions.Sessions) != 1 {
t.Fatalf("bad: %v", sessions.Sessions)
}
}
// Now turn on version 8 enforcement and make sure everything is empty.
s1.config.ACLEnforceVersion8 = true
{
var sessions structs.IndexedSessions
if err := msgpackrpc.CallWithCodec(codec, "Session.Get", &getR, &sessions); err != nil {
t.Fatalf("err: %v", err)
}
if len(sessions.Sessions) != 0 {
t.Fatalf("bad: %v", sessions.Sessions)
}
}
{
var sessions structs.IndexedSessions
if err := msgpackrpc.CallWithCodec(codec, "Session.List", &listR, &sessions); err != nil {
t.Fatalf("err: %v", err)
}
if len(sessions.Sessions) != 0 {
t.Fatalf("bad: %v", sessions.Sessions)
}
}
{ {
var sessions structs.IndexedSessions var sessions structs.IndexedSessions
if err := msgpackrpc.CallWithCodec(codec, "Session.NodeSessions", &nodeR, &sessions); err != nil { if err := msgpackrpc.CallWithCodec(codec, "Session.NodeSessions", &nodeR, &sessions); err != nil {
@ -765,7 +714,6 @@ func TestSession_Renew_ACLDeny(t *testing.T) {
c.ACLsEnabled = true c.ACLsEnabled = true
c.ACLMasterToken = "root" c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny" c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
}) })
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
@ -773,7 +721,7 @@ func TestSession_Renew_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1) codec := rpcClient(t, s1)
defer codec.Close() defer codec.Close()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1") testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create the ACL. // Create the ACL.
req := structs.ACLRequest{ req := structs.ACLRequest{
@ -799,8 +747,7 @@ session "foo" {
// Just add a node. // Just add a node.
s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}) s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"})
// Create a session. The token won't matter here since we don't have // Create a session.
// version 8 ACL enforcement on yet.
arg := structs.SessionRequest{ arg := structs.SessionRequest{
Datacenter: "dc1", Datacenter: "dc1",
Op: structs.SessionCreate, Op: structs.SessionCreate,
@ -808,25 +755,19 @@ session "foo" {
Node: "foo", Node: "foo",
Name: "my-session", Name: "my-session",
}, },
WriteRequest: structs.WriteRequest{Token: token},
} }
var id string var id string
if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &id); err != nil { if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &id); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// Renew without a token should go through without version 8 ACL // Renew without a token should be rejected.
// enforcement.
renewR := structs.SessionSpecificRequest{ renewR := structs.SessionSpecificRequest{
Datacenter: "dc1", Datacenter: "dc1",
SessionID: id, SessionID: id,
} }
var session structs.IndexedSessions var session structs.IndexedSessions
if err := msgpackrpc.CallWithCodec(codec, "Session.Renew", &renewR, &session); err != nil {
t.Fatalf("err: %v", err)
}
// Now turn on version 8 enforcement and the renew should be rejected.
s1.config.ACLEnforceVersion8 = true
err := msgpackrpc.CallWithCodec(codec, "Session.Renew", &renewR, &session) err := msgpackrpc.CallWithCodec(codec, "Session.Renew", &renewR, &session)
if !acl.IsErrPermissionDenied(err) { if !acl.IsErrPermissionDenied(err) {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)

View File

@ -810,7 +810,6 @@ func TestPProfHandlers_ACLs(t *testing.T) {
acl_master_token = "master" acl_master_token = "master"
acl_agent_token = "agent" acl_agent_token = "agent"
acl_agent_master_token = "towel" acl_agent_master_token = "towel"
acl_enforce_version_8 = true
enable_debug = false enable_debug = false
`) `)

View File

@ -754,8 +754,7 @@ func TestAgentAntiEntropy_Services_ACLDeny(t *testing.T) {
a := agent.NewTestAgent(t, ` a := agent.NewTestAgent(t, `
acl_datacenter = "dc1" acl_datacenter = "dc1"
acl_master_token = "root" acl_master_token = "root"
acl_default_policy = "deny" acl_default_policy = "deny" `)
acl_enforce_version_8 = true`)
defer a.Shutdown() defer a.Shutdown()
testrpc.WaitForLeader(t, a.RPC, "dc1") testrpc.WaitForLeader(t, a.RPC, "dc1")
@ -1170,8 +1169,7 @@ func TestAgentAntiEntropy_Checks_ACLDeny(t *testing.T) {
a := &agent.TestAgent{HCL: ` a := &agent.TestAgent{HCL: `
acl_datacenter = "` + dc + `" acl_datacenter = "` + dc + `"
acl_master_token = "root" acl_master_token = "root"
acl_default_policy = "deny" acl_default_policy = "deny" `}
acl_enforce_version_8 = true`}
if err := a.Start(t); err != nil { if err := a.Start(t); err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -470,7 +470,6 @@ func TestACLConfig() string {
acl_master_token = "root" acl_master_token = "root"
acl_agent_token = "root" acl_agent_token = "root"
acl_agent_master_token = "towel" acl_agent_master_token = "towel"
acl_enforce_version_8 = true
` `
} }

View File

@ -38,9 +38,10 @@ func makeACLClient(t *testing.T) (*Client, *testutil.TestServer) {
clientConfig.Token = "root" clientConfig.Token = "root"
}, func(serverConfig *testutil.TestServerConfig) { }, func(serverConfig *testutil.TestServerConfig) {
serverConfig.PrimaryDatacenter = "dc1" serverConfig.PrimaryDatacenter = "dc1"
serverConfig.ACLMasterToken = "root" serverConfig.ACL.Tokens.Master = "root"
serverConfig.ACL.Tokens.Agent = "root"
serverConfig.ACL.Enabled = true serverConfig.ACL.Enabled = true
serverConfig.ACLDefaultPolicy = "deny" serverConfig.ACL.DefaultPolicy = "deny"
}) })
} }

View File

@ -3,7 +3,6 @@ package version
import ( import (
"fmt" "fmt"
"github.com/hashicorp/consul/agent/config"
"github.com/hashicorp/consul/agent/consul" "github.com/hashicorp/consul/agent/consul"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
) )
@ -20,11 +19,8 @@ type cmd struct {
func (c *cmd) Run(_ []string) int { func (c *cmd) Run(_ []string) int {
c.UI.Output(fmt.Sprintf("Consul %s", c.version)) c.UI.Output(fmt.Sprintf("Consul %s", c.version))
rpcProtocol, err := config.DefaultRPCProtocol() const rpcProtocol = consul.DefaultRPCProtocol
if err != nil {
c.UI.Error(err.Error())
return 2
}
var supplement string var supplement string
if rpcProtocol < consul.ProtocolVersionMax { if rpcProtocol < consul.ProtocolVersionMax {
supplement = fmt.Sprintf(" (agent will automatically use protocol >%d when speaking to compatible agents)", supplement = fmt.Sprintf(" (agent will automatically use protocol >%d when speaking to compatible agents)",

View File

@ -88,7 +88,6 @@ type TestServerConfig struct {
ACLDatacenter string `json:"acl_datacenter,omitempty"` ACLDatacenter string `json:"acl_datacenter,omitempty"`
PrimaryDatacenter string `json:"primary_datacenter,omitempty"` PrimaryDatacenter string `json:"primary_datacenter,omitempty"`
ACLDefaultPolicy string `json:"acl_default_policy,omitempty"` ACLDefaultPolicy string `json:"acl_default_policy,omitempty"`
ACLEnforceVersion8 bool `json:"acl_enforce_version_8"`
ACL TestACLs `json:"acl,omitempty"` ACL TestACLs `json:"acl,omitempty"`
Encrypt string `json:"encrypt,omitempty"` Encrypt string `json:"encrypt,omitempty"`
CAFile string `json:"ca_file,omitempty"` CAFile string `json:"ca_file,omitempty"`
@ -381,7 +380,8 @@ func (s *TestServer) waitForAPI() error {
for !time.Now().After(deadline) { for !time.Now().After(deadline) {
time.Sleep(timer.Wait) time.Sleep(timer.Wait)
resp, err := s.HTTPClient.Get(s.url("/v1/agent/self")) url := s.url("/v1/agent/self")
resp, err := s.masterGet(url)
if err != nil { if err != nil {
failed = true failed = true
continue continue
@ -407,7 +407,7 @@ func (s *TestServer) WaitForLeader(t *testing.T) {
retry.Run(t, func(r *retry.R) { retry.Run(t, func(r *retry.R) {
// Query the API and check the status code. // Query the API and check the status code.
url := s.url("/v1/catalog/nodes") url := s.url("/v1/catalog/nodes")
resp, err := s.HTTPClient.Get(url) resp, err := s.masterGet(url)
if err != nil { if err != nil {
r.Fatalf("failed http get '%s': %v", url, err) r.Fatalf("failed http get '%s': %v", url, err)
} }
@ -443,7 +443,7 @@ func (s *TestServer) WaitForActiveCARoot(t *testing.T) {
retry.Run(t, func(r *retry.R) { retry.Run(t, func(r *retry.R) {
// Query the API and check the status code. // Query the API and check the status code.
url := s.url("/v1/agent/connect/ca/roots") url := s.url("/v1/agent/connect/ca/roots")
resp, err := s.HTTPClient.Get(url) resp, err := s.masterGet(url)
if err != nil { if err != nil {
r.Fatalf("failed http get '%s': %v", url, err) r.Fatalf("failed http get '%s': %v", url, err)
} }
@ -475,7 +475,7 @@ func (s *TestServer) WaitForSerfCheck(t *testing.T) {
retry.Run(t, func(r *retry.R) { retry.Run(t, func(r *retry.R) {
// Query the API and check the status code. // Query the API and check the status code.
url := s.url("/v1/catalog/nodes?index=0") url := s.url("/v1/catalog/nodes?index=0")
resp, err := s.HTTPClient.Get(url) resp, err := s.masterGet(url)
if err != nil { if err != nil {
r.Fatal("failed http get", err) r.Fatal("failed http get", err)
} }
@ -496,7 +496,7 @@ func (s *TestServer) WaitForSerfCheck(t *testing.T) {
// Ensure the serfHealth check is registered // Ensure the serfHealth check is registered
url = s.url(fmt.Sprintf("/v1/health/node/%s", payload[0]["Node"])) url = s.url(fmt.Sprintf("/v1/health/node/%s", payload[0]["Node"]))
resp, err = s.HTTPClient.Get(url) resp, err = s.masterGet(url)
if err != nil { if err != nil {
r.Fatal("failed http get", err) r.Fatal("failed http get", err)
} }
@ -521,3 +521,14 @@ func (s *TestServer) WaitForSerfCheck(t *testing.T) {
} }
}) })
} }
func (s *TestServer) masterGet(url string) (*http.Response, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
if s.Config.ACL.Tokens.Master != "" {
req.Header.Set("x-consul-token", s.Config.ACL.Tokens.Master)
}
return s.HTTPClient.Do(req)
}

View File

@ -11,12 +11,20 @@ import (
type rpcFn func(string, interface{}, interface{}) error type rpcFn func(string, interface{}, interface{}) error
// WaitForLeader ensures we have a leader and a node registration. // WaitForLeader ensures we have a leader and a node registration.
func WaitForLeader(t *testing.T, rpc rpcFn, dc string) { func WaitForLeader(t *testing.T, rpc rpcFn, dc string, options ...waitOption) {
t.Helper() t.Helper()
flat := flattenOptions(options)
if flat.WaitForAntiEntropySync {
t.Fatalf("WaitForLeader doesn't accept the WaitForAntiEntropySync option")
}
var out structs.IndexedNodes var out structs.IndexedNodes
retry.Run(t, func(r *retry.R) { retry.Run(t, func(r *retry.R) {
args := &structs.DCSpecificRequest{Datacenter: dc} args := &structs.DCSpecificRequest{
Datacenter: dc,
QueryOptions: structs.QueryOptions{Token: flat.Token},
}
if err := rpc("Catalog.ListNodes", args, &out); err != nil { if err := rpc("Catalog.ListNodes", args, &out); err != nil {
r.Fatalf("Catalog.ListNodes failed: %v", err) r.Fatalf("Catalog.ListNodes failed: %v", err)
} }
@ -30,12 +38,20 @@ func WaitForLeader(t *testing.T, rpc rpcFn, dc string) {
} }
// WaitUntilNoLeader ensures no leader is present, useful for testing lost leadership. // WaitUntilNoLeader ensures no leader is present, useful for testing lost leadership.
func WaitUntilNoLeader(t *testing.T, rpc rpcFn, dc string) { func WaitUntilNoLeader(t *testing.T, rpc rpcFn, dc string, options ...waitOption) {
t.Helper() t.Helper()
flat := flattenOptions(options)
if flat.WaitForAntiEntropySync {
t.Fatalf("WaitUntilNoLeader doesn't accept the WaitForAntiEntropySync option")
}
var out structs.IndexedNodes var out structs.IndexedNodes
retry.Run(t, func(r *retry.R) { retry.Run(t, func(r *retry.R) {
args := &structs.DCSpecificRequest{Datacenter: dc} args := &structs.DCSpecificRequest{
Datacenter: dc,
QueryOptions: structs.QueryOptions{Token: flat.Token},
}
if err := rpc("Catalog.ListNodes", args, &out); err == nil { if err := rpc("Catalog.ListNodes", args, &out); err == nil {
r.Fatalf("It still has a leader: %#v", out) r.Fatalf("It still has a leader: %#v", out)
} }
@ -58,30 +74,32 @@ func WaitForAntiEntropySync() waitOption {
return waitOption{WaitForAntiEntropySync: true} return waitOption{WaitForAntiEntropySync: true}
} }
func flattenOptions(options []waitOption) waitOption {
var flat waitOption
for _, opt := range options {
if opt.Token != "" {
flat.Token = opt.Token
}
if opt.WaitForAntiEntropySync {
flat.WaitForAntiEntropySync = true
}
}
return flat
}
// WaitForTestAgent ensures we have a node with serfHealth check registered // WaitForTestAgent ensures we have a node with serfHealth check registered
func WaitForTestAgent(t *testing.T, rpc rpcFn, dc string, options ...waitOption) { func WaitForTestAgent(t *testing.T, rpc rpcFn, dc string, options ...waitOption) {
t.Helper() t.Helper()
flat := flattenOptions(options)
var nodes structs.IndexedNodes var nodes structs.IndexedNodes
var checks structs.IndexedHealthChecks var checks structs.IndexedHealthChecks
var (
token string
waitForAntiEntropySync bool
)
for _, opt := range options {
if opt.Token != "" {
token = opt.Token
}
if opt.WaitForAntiEntropySync {
waitForAntiEntropySync = true
}
}
retry.Run(t, func(r *retry.R) { retry.Run(t, func(r *retry.R) {
dcReq := &structs.DCSpecificRequest{ dcReq := &structs.DCSpecificRequest{
Datacenter: dc, Datacenter: dc,
QueryOptions: structs.QueryOptions{Token: token}, QueryOptions: structs.QueryOptions{Token: flat.Token},
} }
if err := rpc("Catalog.ListNodes", dcReq, &nodes); err != nil { if err := rpc("Catalog.ListNodes", dcReq, &nodes); err != nil {
r.Fatalf("Catalog.ListNodes failed: %v", err) r.Fatalf("Catalog.ListNodes failed: %v", err)
@ -90,7 +108,7 @@ func WaitForTestAgent(t *testing.T, rpc rpcFn, dc string, options ...waitOption)
r.Fatalf("No registered nodes") r.Fatalf("No registered nodes")
} }
if waitForAntiEntropySync { if flat.WaitForAntiEntropySync {
if len(nodes.Nodes[0].TaggedAddresses) == 0 { if len(nodes.Nodes[0].TaggedAddresses) == 0 {
r.Fatalf("Not synced via anti entropy yet") r.Fatalf("Not synced via anti entropy yet")
} }
@ -100,7 +118,7 @@ func WaitForTestAgent(t *testing.T, rpc rpcFn, dc string, options ...waitOption)
nodeReq := &structs.NodeSpecificRequest{ nodeReq := &structs.NodeSpecificRequest{
Datacenter: dc, Datacenter: dc,
Node: nodes.Nodes[0].Node, Node: nodes.Nodes[0].Node,
QueryOptions: structs.QueryOptions{Token: token}, QueryOptions: structs.QueryOptions{Token: flat.Token},
} }
if err := rpc("Health.NodeChecks", nodeReq, &checks); err != nil { if err := rpc("Health.NodeChecks", nodeReq, &checks); err != nil {
r.Fatalf("Health.NodeChecks failed: %v", err) r.Fatalf("Health.NodeChecks failed: %v", err)

View File

@ -735,7 +735,7 @@ Valid time units are 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'."
of the node-level information in the catalog such as metadata, or the node's tagged addresses. of the node-level information in the catalog such as metadata, or the node's tagged addresses.
- `acl_enforce_version_8` - **Deprecated in - `acl_enforce_version_8` - **Deprecated in
Consul 1.4.0** Used for clients and servers to determine if enforcement should Consul 1.4.0 and removed in 1.8.0.** 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, occur for new ACL policies being previewed before Consul 0.8. Added in Consul 0.7.2,
this defaults to false in versions of Consul prior to 0.8, and defaults to true this defaults to false in versions of Consul prior to 0.8, and defaults to true
in Consul 0.8 and later. This helps ease the transition to the new ACL features in Consul 0.8 and later. This helps ease the transition to the new ACL features

View File

@ -15,6 +15,12 @@ provided for their upgrades as a result of new features or changed behavior.
This page is used to document those details separately from the standard This page is used to document those details separately from the standard
upgrade flow. upgrade flow.
## Consul 1.8.0
The [`acl_enforce_version_8`](/docs/agent/options#acl_enforce_version_8)
configuration has been removed (with version 8 ACL support by being on by
default).
## Consul 1.7.0 ## Consul 1.7.0
Consul 1.7.0 contains three major changes that impact upgrades: Consul 1.7.0 contains three major changes that impact upgrades: