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

Fixes #7292
This commit is contained in:
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
}
// Disable ACLs if version 8 enforcement isn't enabled.
if !a.config.ACLEnforceVersion8 {
return nil, nil
}
if acl.RootAuthorizer(id) != nil {
return nil, acl.ErrRootDenied
}

View File

@ -181,33 +181,19 @@ func (a *TestACLAgent) ReloadConfig(config *consul.Config) error {
return fmt.Errorf("Unimplemented")
}
func TestACL_Version8(t *testing.T) {
func TestACL_Version8EnabledByDefault(t *testing.T) {
t.Parallel()
t.Run("version 8 disabled", func(t *testing.T) {
a := NewTestACLAgent(t, t.Name(), TestACLConfig()+`
acl_enforce_version_8 = false
`, nil, nil)
token, err := a.resolveToken("nope")
require.Nil(t, token)
require.Nil(t, err)
})
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)
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), resolveFn, nil)
_, err := a.resolveToken("nope")
require.Error(t, err)
require.True(t, called)
})
}
func TestACL_AgentMasterToken(t *testing.T) {

View File

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

View File

@ -1307,7 +1307,6 @@ func TestAgent_Reload(t *testing.T) {
t.Parallel()
dc1 := "dc1"
a := NewTestAgent(t, `
acl_enforce_version_8 = false
services = [
{
name = "redis"
@ -1341,7 +1340,6 @@ func TestAgent_Reload(t *testing.T) {
node_id = "` + string(a.Config.NodeID) + `"
node_name = "` + a.Config.NodeName + `"
acl_enforce_version_8 = false
services = [
{
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)
a := NewTestAgent(t, `
acl_enforce_version_8 = false
services = [
{
name = "redis"
@ -1477,7 +1474,6 @@ func TestAgent_ReloadDoesNotTriggerWatch(t *testing.T) {
node_id = "` + string(a.Config.NodeID) + `"
node_name = "` + a.Config.NodeName + `"
acl_enforce_version_8 = false
services = [
{
name = "redis"
@ -6031,7 +6027,6 @@ func TestAgentConnectAuthorize_defaultAllow(t *testing.T) {
acl_master_token = "root"
acl_agent_token = "root"
acl_agent_master_token = "towel"
acl_enforce_version_8 = true
`)
defer a.Shutdown()
testrpc.WaitForTestAgent(t, a.RPC, dc1)
@ -6063,7 +6058,6 @@ func TestAgent_Host(t *testing.T) {
acl_master_token = "master"
acl_agent_token = "agent"
acl_agent_master_token = "towel"
acl_enforce_version_8 = true
`)
defer a.Shutdown()
@ -6091,7 +6085,6 @@ func TestAgent_HostBadACL(t *testing.T) {
acl_master_token = "root"
acl_agent_token = "agent"
acl_agent_master_token = "towel"
acl_enforce_version_8 = true
`)
defer a.Shutdown()

View File

@ -279,13 +279,26 @@ func (b *Builder) Build() (rt RuntimeConfig, err error) {
if s.Name == "" || s.Data == "" {
continue
}
c2, keys, err := Parse(s.Data, s.Format)
c2, md, err := Parse(s.Data, s.Format)
if err != nil {
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
b.validateEnterpriseConfigKeys(&c2, keys)
b.validateEnterpriseConfigKeys(&c2, md.Keys)
// 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
@ -790,7 +803,6 @@ func (b *Builder) Build() (rt RuntimeConfig, err error) {
GossipWANRetransmitMult: b.intVal(c.GossipWAN.RetransmitMult),
// ACL
ACLEnforceVersion8: b.boolValWithDefault(c.ACLEnforceVersion8, true),
ACLsEnabled: aclsEnabled,
ACLAgentMasterToken: b.stringValWithDefault(c.ACL.Tokens.AgentMaster, b.stringVal(c.ACLAgentMasterToken)),
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/decode"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/hcl"
"github.com/mitchellh/mapstructure"
)
@ -35,7 +34,7 @@ func FormatFrom(name string) string {
}
// 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{}
switch format {
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)
}
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
@ -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)
})
var md mapstructure.Metadata
d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
DecodeHook: decode.HookTranslateKeys,
Metadata: &md,
Result: &c,
})
if err != nil {
return Config{}, nil, err
return Config{}, mapstructure.Metadata{}, err
}
if err := d.Decode(m); err != nil {
return Config{}, nil, err
return Config{}, mapstructure.Metadata{}, err
}
for _, k := range md.Unused {
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
return c, md, nil
}
// 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"`
// 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"`
// 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
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

View File

@ -10,18 +10,6 @@ import (
"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.
// This needs to be merged first in the head.
// todo(fs): The values are sourced from multiple sources.
@ -43,7 +31,6 @@ func DefaultSource() Source {
Data: `
acl_default_policy = "allow"
acl_down_policy = "extend-cache"
acl_enforce_version_8 = true
acl_ttl = "30s"
acl = {
policy_ttl = "30s"
@ -65,7 +52,7 @@ func DefaultSource() Source {
log_level = "INFO"
max_query_time = "600s"
primary_gateways_interval = "30s"
protocol = 2
protocol = ` + strconv.Itoa(consul.DefaultRPCProtocol) + `
retry_interval = "30s"
retry_interval_wan = "30s"
server = false

View File

@ -104,13 +104,6 @@ type RuntimeConfig struct {
// hcl: acl.down_policy = ("allow"|"deny"|"extend-cache"|"async-cache")
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
// KV ACLs in Consul 1.0.
//

View File

@ -1619,6 +1619,16 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
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",
args: []string{`-data-dir=` + dataDir},
@ -3934,7 +3944,6 @@ func TestFullConfig(t *testing.T) {
"acl_datacenter": "m3urck3z",
"acl_default_policy": "ArK3WIfE",
"acl_down_policy": "vZXMfMP0",
"acl_enforce_version_8": true,
"acl_enable_key_list_policy": true,
"acl_master_token": "C1Q1oIwh",
"acl_replication_token": "LMmgy5dO",
@ -4570,7 +4579,6 @@ func TestFullConfig(t *testing.T) {
acl_datacenter = "m3urck3z"
acl_default_policy = "ArK3WIfE"
acl_down_policy = "vZXMfMP0"
acl_enforce_version_8 = true
acl_enable_key_list_policy = true
acl_master_token = "C1Q1oIwh"
acl_replication_token = "LMmgy5dO"
@ -5332,7 +5340,6 @@ func TestFullConfig(t *testing.T) {
ACLDatacenter: "ejtmd43d",
ACLDefaultPolicy: "72c2e7a0",
ACLDownPolicy: "03eb2aee",
ACLEnforceVersion8: true,
ACLEnableKeyListPolicy: true,
ACLEnableTokenPersistence: true,
ACLMasterToken: "8a19ac27",
@ -6251,7 +6258,6 @@ func TestSanitize(t *testing.T) {
"ACLDownPolicy": "",
"ACLEnableKeyListPolicy": false,
"ACLEnableTokenPersistence": false,
"ACLEnforceVersion8": false,
"ACLMasterToken": "hidden",
"ACLPolicyTTL": "0s",
"ACLReplicationToken": "hidden",

View File

@ -1171,27 +1171,21 @@ func (r *ACLResolver) GetMergedPolicyForToken(token string) (*acl.Policy, error)
type aclFilter struct {
authorizer acl.Authorizer
logger hclog.Logger
enforceVersion8 bool
}
// 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 {
logger = hclog.New(&hclog.LoggerOptions{})
}
return &aclFilter{
authorizer: authorizer,
logger: logger,
enforceVersion8: enforceVersion8,
}
}
// allowNode is used to determine if a node is accessible for an ACL.
func (f *aclFilter) allowNode(node string, ent *acl.AuthorizerContext) bool {
if !f.enforceVersion8 {
return true
}
return f.authorizer.NodeRead(node, ent) == acl.Allow
}
@ -1218,18 +1212,12 @@ func (f *aclFilter) allowService(service string, ent *acl.AuthorizerContext) boo
return true
}
if !f.enforceVersion8 && service == structs.ConsulServiceID {
return true
}
return f.authorizer.ServiceRead(service, ent) == acl.Allow
}
// allowSession is used to determine if a session for a node is accessible for
// an ACL.
func (f *aclFilter) allowSession(node string, ent *acl.AuthorizerContext) bool {
if !f.enforceVersion8 {
return true
}
return f.authorizer.SessionRead(node, ent) == acl.Allow
}
@ -1793,7 +1781,7 @@ func (r *ACLResolver) filterACLWithAuthorizer(authorizer acl.Authorizer, subj in
return nil
}
// Create the filter
filt := newACLFilter(authorizer, r.logger, r.config.ACLEnforceVersion8)
filt := newACLFilter(authorizer, r.logger)
switch v := subj.(type) {
case *structs.CheckServiceNodes:

View File

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

View File

@ -163,11 +163,10 @@ func TestCatalog_Register_ACLDeny(t *testing.T) {
c.ACLsEnabled = true
c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1)
defer codec.Close()
@ -182,6 +181,9 @@ func TestCatalog_Register_ACLDeny(t *testing.T) {
service "foo" {
policy = "write"
}
node "foo" {
policy = "write"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
@ -218,18 +220,9 @@ service "foo" {
t.Fatalf("err: %v", err)
}
// Try the special case for the "consul" service that allows it no matter
// what with pre-version 8 ACL enforcement.
// Try the former special case for the "consul" service.
argR.Service.Service = "consul"
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) {
t.Fatalf("err: %v", err)
}
@ -415,6 +408,9 @@ func TestCatalog_Register_ConnectProxy_ACLDestinationServiceName(t *testing.T) {
service "foo" {
policy = "write"
}
node "foo" {
policy = "write"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
@ -510,7 +506,6 @@ func TestCatalog_Deregister_ACLDeny(t *testing.T) {
c.ACLsEnabled = true
c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
@ -570,50 +565,9 @@ service "service" {
t.Fatalf("err: %v", err)
}
// First pass with version 8 ACL enforcement disabled, we should be able
// to deregister everything even without a token.
// We should be not be able to deregister everything without a token.
var err error
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",
&structs.DeregisterRequest{
Datacenter: "dc1",
@ -646,7 +600,7 @@ service "service" {
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",
&structs.DeregisterRequest{
Datacenter: "dc1",
@ -1237,7 +1191,6 @@ func TestCatalog_ListNodes_ACLFilter(t *testing.T) {
c.ACLsEnabled = true
c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
})
defer os.RemoveAll(dir1)
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
// clean each time.
// Prior to version 8, the node policy should be ignored.
// The node policy should not be ignored.
args := structs.DCSpecificRequest{
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{}
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) {
t.Parallel()
assert := assert.New(t)
dir1, s1 := testServerWithConfig(t, func(c *Config) {
c.ACLDatacenter = "dc1"
c.ACLsEnabled = true
@ -2310,12 +2250,13 @@ func TestCatalog_ListServiceNodes_ConnectProxy_ACL(t *testing.T) {
service "foo" {
policy = "write"
}
node "" { policy = "read" }
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
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
@ -2324,21 +2265,21 @@ service "foo" {
args.Service.Proxy.DestinationServiceName = "bar"
args.WriteRequest.Token = "root"
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
args = structs.TestRegisterRequestProxy(t)
args.Service.Service = "foo-proxy"
args.Service.Proxy.DestinationServiceName = "foo"
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
args = structs.TestRegisterRequestProxy(t)
args.Service.Service = "another-proxy"
args.Service.Proxy.DestinationServiceName = "foo"
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
@ -2350,8 +2291,8 @@ service "foo" {
QueryOptions: structs.QueryOptions{Token: token},
}
var resp structs.IndexedServiceNodes
assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
assert.Len(resp.ServiceNodes, 0)
require.NoError(t, msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
require.Len(t, resp.ServiceNodes, 0)
// 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.
@ -2361,10 +2302,11 @@ service "foo" {
ServiceName: "foo",
QueryOptions: structs.QueryOptions{Token: token},
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
assert.Len(resp.ServiceNodes, 1)
resp = structs.IndexedServiceNodes{}
require.NoError(t, msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
require.Len(t, resp.ServiceNodes, 1)
v := resp.ServiceNodes[0]
assert.Equal("foo-proxy", v.ServiceName)
require.Equal(t, "foo-proxy", v.ServiceName)
}
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.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
})
codec = rpcClient(t, srv)
testrpc.WaitForLeader(t, srv.RPC, "dc1")
testrpc.WaitForTestAgent(t, srv.RPC, "dc1", testrpc.WithToken("root"))
// Create a new token
arg := structs.ACLRequest{
@ -2581,6 +2522,9 @@ func testACLFilterServer(t *testing.T) (dir, token string, srv *Server, codec rp
service "foo" {
policy = "write"
}
node "" {
policy = "read"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
@ -2638,7 +2582,7 @@ func TestCatalog_ListServices_FilterACL(t *testing.T) {
defer os.RemoveAll(dir)
defer srv.Shutdown()
defer codec.Close()
testrpc.WaitForTestAgent(t, srv.RPC, "dc1")
testrpc.WaitForTestAgent(t, srv.RPC, "dc1", testrpc.WithToken("root"))
opt := structs.DCSpecificRequest{
Datacenter: "dc1",
@ -2713,16 +2657,15 @@ func TestCatalog_NodeServices_ACLDeny(t *testing.T) {
c.ACLsEnabled = true
c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
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{
Datacenter: "dc1",
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 {
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 {
t.Fatalf("should not nil")
}
@ -2789,28 +2723,21 @@ func TestCatalog_NodeServices_FilterACL(t *testing.T) {
defer os.RemoveAll(dir)
defer srv.Shutdown()
defer codec.Close()
testrpc.WaitForTestAgent(t, srv.RPC, "dc1")
testrpc.WaitForTestAgent(t, srv.RPC, "dc1", testrpc.WithToken("root"))
opt := structs.NodeSpecificRequest{
Datacenter: "dc1",
Node: srv.config.NodeName,
QueryOptions: structs.QueryOptions{Token: token},
}
reply := structs.IndexedNodeServices{}
if err := msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &opt, &reply); err != nil {
t.Fatalf("err: %s", err)
}
found := false
for _, svc := range reply.NodeServices.Services {
if svc.ID == "bar" {
t.Fatalf("bad: %#v", reply.NodeServices.Services)
}
if svc.ID == "foo" {
found = true
break
}
}
if !found {
t.Fatalf("bad: %#v", reply.NodeServices)
}
var reply structs.IndexedNodeServices
require.NoError(t, msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &opt, &reply))
require.NotNil(t, reply.NodeServices)
require.Len(t, reply.NodeServices.Services, 1)
svc, ok := reply.NodeServices.Services["foo"]
require.True(t, ok)
require.Equal(t, "foo", svc.ID)
}

View File

@ -237,10 +237,6 @@ type Config struct {
// ACLEnabled is used to enable ACLs
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
// on the servers in the ACLDatacenter. When the leader comes online, it ensures
// 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 s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1)
defer codec.Close()
@ -266,7 +266,7 @@ func TestConfigEntry_Get_ACLDeny(t *testing.T) {
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1)
defer codec.Close()
@ -421,7 +421,7 @@ func TestConfigEntry_List_ACLDeny(t *testing.T) {
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1)
defer codec.Close()
@ -502,7 +502,7 @@ func TestConfigEntry_ListAll_ACLDeny(t *testing.T) {
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1)
defer codec.Close()
@ -652,7 +652,7 @@ func TestConfigEntry_Delete_ACLDeny(t *testing.T) {
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1)
defer codec.Close()
@ -1119,7 +1119,7 @@ func TestConfigEntry_ResolveServiceConfig_ACLDeny(t *testing.T) {
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
codec := rpcClient(t, s1)
defer codec.Close()

View File

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

View File

@ -15,7 +15,7 @@ import (
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/sdk/testutil/retry"
"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/pascaldekloe/goe/verify"
)
@ -51,7 +51,7 @@ func TestCoordinate_Update(t *testing.T) {
// Register some nodes.
nodes := []string{"node1", "node2"}
if err := registerNodes(nodes, codec); err != nil {
if err := registerNodes(nodes, codec, ""); err != nil {
t.Fatal(err)
}
@ -184,22 +184,21 @@ func TestCoordinate_Update_ACLDeny(t *testing.T) {
c.ACLsEnabled = true
c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1")
testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Register some nodes.
nodes := []string{"node1", "node2"}
if err := registerNodes(nodes, codec); err != nil {
if err := registerNodes(nodes, codec, "root"); err != nil {
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.
req := structs.CoordinateUpdateRequest{
Datacenter: "dc1",
@ -207,12 +206,6 @@ func TestCoordinate_Update_ACLDeny(t *testing.T) {
Coord: generateRandomCoordinate(),
}
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)
if !acl.IsErrPermissionDenied(err) {
t.Fatalf("err: %v", err)
@ -295,7 +288,7 @@ func TestCoordinate_ListNodes(t *testing.T) {
// Register some nodes.
nodes := []string{"foo", "bar", "baz"}
if err := registerNodes(nodes, codec); err != nil {
if err := registerNodes(nodes, codec, ""); err != nil {
t.Fatal(err)
}
@ -355,14 +348,13 @@ func TestCoordinate_ListNodes_ACLFilter(t *testing.T) {
c.ACLsEnabled = true
c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1")
testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Register some nodes.
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 {
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
// everything back without a token.
// Wait for all the coordinate updates to apply.
retry.Run(t, func(r *retry.R) {
arg := structs.DCSpecificRequest{
Datacenter: "dc1",
QueryOptions: structs.QueryOptions{Token: "root"},
}
resp := structs.IndexedCoordinates{}
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
// coordinates we can do the rest of the requests without the loop. We
// will start by turning on version 8 ACL support which should block
// everything.
s1.config.ACLEnforceVersion8 = true
// coordinates we can do the rest of the requests without the loop.
arg := structs.DCSpecificRequest{
Datacenter: "dc1",
}
@ -494,7 +483,7 @@ func TestCoordinate_Node(t *testing.T) {
// Register some nodes.
nodes := []string{"foo", "bar"}
if err := registerNodes(nodes, codec); err != nil {
if err := registerNodes(nodes, codec, ""); err != nil {
t.Fatal(err)
}
@ -543,18 +532,17 @@ func TestCoordinate_Node_ACLDeny(t *testing.T) {
c.ACLsEnabled = true
c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1")
testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Register some nodes.
nodes := []string{"node1", "node2"}
if err := registerNodes(nodes, codec); err != nil {
if err := registerNodes(nodes, codec, "root"); err != nil {
t.Fatal(err)
}
@ -563,32 +551,19 @@ func TestCoordinate_Node_ACLDeny(t *testing.T) {
Datacenter: "dc1",
Node: "node1",
Coord: coord,
WriteRequest: structs.WriteRequest{Token: "root"},
}
var out struct{}
if err := msgpackrpc.CallWithCodec(codec, "Coordinate.Update", &req, &out); err != nil {
t.Fatalf("err: %v", err)
}
// Try a read for the first node. This should go through since we
// don't have version 8 ACLs enforced yet.
// Try a read for the first node. This should fail without a token.
arg := structs.NodeSpecificRequest{
Node: "node1",
Datacenter: "dc1",
}
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)
if !acl.IsErrPermissionDenied(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 {
req := structs.RegisterRequest{
Datacenter: "dc1",
Node: node,
Address: "127.0.0.1",
WriteRequest: structs.WriteRequest{Token: token},
}
var reply struct{}
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)
defer codec.Close()
testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
testrpc.WaitForLeader(t, s1.RPC, "dc1")
waitForLeaderEstablishment(t, s1)
testrpc.WaitForTestAgent(t, s1.RPC, "dc1", testrpc.WithToken("root"))
denyToken, err := upsertTestTokenWithPolicyRules(codec, "root", "dc1", "")
require.NoError(t, err)

View File

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

View File

@ -936,14 +936,13 @@ func TestHealth_ServiceNodes_ConnectProxy_ACL(t *testing.T) {
c.ACLsEnabled = true
c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = false
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1")
testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create the ACL.
arg := structs.ACLRequest{
@ -956,6 +955,9 @@ func TestHealth_ServiceNodes_ConnectProxy_ACL(t *testing.T) {
service "foo" {
policy = "write"
}
node "foo" {
policy = "write"
}
`,
},
WriteRequest: structs.WriteRequest{Token: "root"},
@ -1236,14 +1238,13 @@ func TestHealth_ServiceNodes_Ingress_ACL(t *testing.T) {
c.ACLsEnabled = true
c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1")
testrpc.WaitForLeader(t, s1.RPC, "dc1", testrpc.WithToken("root"))
// Create the ACL.
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) {
c.ACLDatacenter = "dc1"
c.ACLsEnabled = true
c.ACLEnforceVersion8 = true
c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
})
@ -1355,7 +1354,6 @@ func TestInternal_GatewayServiceDump_Terminating_ACL(t *testing.T) {
c.ACLsEnabled = true
c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
@ -1691,7 +1689,6 @@ func TestInternal_GatewayServiceDump_Ingress_ACL(t *testing.T) {
c.ACLsEnabled = true
c.ACLMasterToken = "root"
c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()

View File

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

View File

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

View File

@ -71,7 +71,7 @@ func TestOperator_RaftGetConfiguration_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1)
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.
arg := structs.DCSpecificRequest{
@ -211,7 +211,7 @@ func TestOperator_RaftRemovePeerByAddress_ACLDeny(t *testing.T) {
codec := rpcClient(t, s1)
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.
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.
switch args.Op {
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)
}
@ -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
// checked, as noted in the comments below. This also updates all the parsed
// fields of the query.
func parseQuery(query *structs.PreparedQuery, enforceVersion8 bool) error {
func parseQuery(query *structs.PreparedQuery) error {
// We skip a few fields:
// - ID is checked outside this fn.
// - Name is optional with no restrictions, except for uniqueness which
@ -142,11 +142,9 @@ func parseQuery(query *structs.PreparedQuery, enforceVersion8 bool) error {
// compile it.
// Anonymous queries require a session or need to be part of a template.
if enforceVersion8 {
if query.Name == "" && query.Template.Type == "" && query.Session == "" {
return fmt.Errorf("Must be bound to a session")
}
}
// Token is checked when the query is executed, but we do make sure the
// user hasn't accidentally pasted-in the special redacted token name,

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

View File

@ -46,6 +46,8 @@ import (
// Consul-level protocol versions, that are used to configure the Serf
// protocol versions.
const (
DefaultRPCProtocol = 2
ProtocolVersionMin uint8 = 2
// 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.ACLMasterToken = TestDefaultMasterToken
c.ACLDefaultPolicy = "deny"
c.ACLEnforceVersion8 = true
if cb != nil {
cb(c)

View File

@ -59,7 +59,7 @@ func (s *Session) Apply(args *structs.SessionRequest, reply *string) error {
return err
}
if authz != nil && s.srv.config.ACLEnforceVersion8 {
if authz != nil {
switch args.Op {
case structs.SessionDestroy:
state := s.srv.fsm.State()
@ -302,7 +302,7 @@ func (s *Session) Renew(args *structs.SessionSpecificRequest,
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
}

View File

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

View File

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

View File

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

View File

@ -470,7 +470,6 @@ func TestACLConfig() string {
acl_master_token = "root"
acl_agent_token = "root"
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"
}, func(serverConfig *testutil.TestServerConfig) {
serverConfig.PrimaryDatacenter = "dc1"
serverConfig.ACLMasterToken = "root"
serverConfig.ACL.Tokens.Master = "root"
serverConfig.ACL.Tokens.Agent = "root"
serverConfig.ACL.Enabled = true
serverConfig.ACLDefaultPolicy = "deny"
serverConfig.ACL.DefaultPolicy = "deny"
})
}

View File

@ -3,7 +3,6 @@ package version
import (
"fmt"
"github.com/hashicorp/consul/agent/config"
"github.com/hashicorp/consul/agent/consul"
"github.com/mitchellh/cli"
)
@ -20,11 +19,8 @@ type cmd struct {
func (c *cmd) Run(_ []string) int {
c.UI.Output(fmt.Sprintf("Consul %s", c.version))
rpcProtocol, err := config.DefaultRPCProtocol()
if err != nil {
c.UI.Error(err.Error())
return 2
}
const rpcProtocol = consul.DefaultRPCProtocol
var supplement string
if rpcProtocol < consul.ProtocolVersionMax {
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"`
PrimaryDatacenter string `json:"primary_datacenter,omitempty"`
ACLDefaultPolicy string `json:"acl_default_policy,omitempty"`
ACLEnforceVersion8 bool `json:"acl_enforce_version_8"`
ACL TestACLs `json:"acl,omitempty"`
Encrypt string `json:"encrypt,omitempty"`
CAFile string `json:"ca_file,omitempty"`
@ -381,7 +380,8 @@ func (s *TestServer) waitForAPI() error {
for !time.Now().After(deadline) {
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 {
failed = true
continue
@ -407,7 +407,7 @@ func (s *TestServer) WaitForLeader(t *testing.T) {
retry.Run(t, func(r *retry.R) {
// Query the API and check the status code.
url := s.url("/v1/catalog/nodes")
resp, err := s.HTTPClient.Get(url)
resp, err := s.masterGet(url)
if err != nil {
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) {
// Query the API and check the status code.
url := s.url("/v1/agent/connect/ca/roots")
resp, err := s.HTTPClient.Get(url)
resp, err := s.masterGet(url)
if err != nil {
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) {
// Query the API and check the status code.
url := s.url("/v1/catalog/nodes?index=0")
resp, err := s.HTTPClient.Get(url)
resp, err := s.masterGet(url)
if err != nil {
r.Fatal("failed http get", err)
}
@ -496,7 +496,7 @@ func (s *TestServer) WaitForSerfCheck(t *testing.T) {
// Ensure the serfHealth check is registered
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 {
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
// 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()
flat := flattenOptions(options)
if flat.WaitForAntiEntropySync {
t.Fatalf("WaitForLeader doesn't accept the WaitForAntiEntropySync option")
}
var out structs.IndexedNodes
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 {
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.
func WaitUntilNoLeader(t *testing.T, rpc rpcFn, dc string) {
func WaitUntilNoLeader(t *testing.T, rpc rpcFn, dc string, options ...waitOption) {
t.Helper()
flat := flattenOptions(options)
if flat.WaitForAntiEntropySync {
t.Fatalf("WaitUntilNoLeader doesn't accept the WaitForAntiEntropySync option")
}
var out structs.IndexedNodes
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 {
r.Fatalf("It still has a leader: %#v", out)
}
@ -58,30 +74,32 @@ func WaitForAntiEntropySync() waitOption {
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
func WaitForTestAgent(t *testing.T, rpc rpcFn, dc string, options ...waitOption) {
t.Helper()
flat := flattenOptions(options)
var nodes structs.IndexedNodes
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) {
dcReq := &structs.DCSpecificRequest{
Datacenter: dc,
QueryOptions: structs.QueryOptions{Token: token},
QueryOptions: structs.QueryOptions{Token: flat.Token},
}
if err := rpc("Catalog.ListNodes", dcReq, &nodes); err != nil {
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")
}
if waitForAntiEntropySync {
if flat.WaitForAntiEntropySync {
if len(nodes.Nodes[0].TaggedAddresses) == 0 {
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{
Datacenter: dc,
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 {
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.
- `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,
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

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
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 contains three major changes that impact upgrades: