Miscellaneous Fixes (#6896)

Ensure we close the Sentinel Evaluator so as not to leak go routines

Fix a bunch of test logging so that various warnings when starting a test agent go to the ltest logger and not straight to stdout.

Various canned ent meta types always return a valid pointer (no more nils). This allows us to blindly deref + assign in various places.

Update ACL index tracking to ensure oss -> ent upgrades will work as expected.

Update ent meta parsing to include function to disallow wildcarding.
This commit is contained in:
Matt Keeler 2019-12-06 14:01:34 -05:00 committed by GitHub
parent a704ebe639
commit 8f0ab0129e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 130 additions and 117 deletions

View File

@ -4,3 +4,5 @@ package acl
// EnterpriseACLConfig stub
type EnterpriseACLConfig struct{}
func (_ *EnterpriseACLConfig) Close() {}

View File

@ -4,7 +4,6 @@ import (
"fmt"
"io"
"log"
"os"
"testing"
"time"
@ -16,6 +15,7 @@ import (
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/logger"
"github.com/hashicorp/consul/sdk/testutil"
"github.com/hashicorp/consul/types"
"github.com/hashicorp/serf/serf"
@ -55,28 +55,27 @@ type TestACLAgent struct {
// NewTestACLAGent does just enough so that all the code within agent/acl.go can work
// Basically it needs a local state for some of the vet* functions, a logger and a delegate.
// The key is that we are the delegate so we can control the ResolveToken responses
func NewTestACLAgent(name string, hcl string, resolveFn func(string) (acl.Authorizer, error)) *TestACLAgent {
func NewTestACLAgent(t *testing.T, name string, hcl string, resolveFn func(string) (acl.Authorizer, error)) *TestACLAgent {
a := &TestACLAgent{Name: name, HCL: hcl, resolveTokenFn: resolveFn}
hclDataDir := `data_dir = "acl-agent"`
a.Config = TestConfig(
logOutput := testutil.TestWriter(t)
logger := log.New(logOutput, a.Name+" - ", log.LstdFlags|log.Lmicroseconds)
a.Config = TestConfig(logger,
config.Source{Name: a.Name, Format: "hcl", Data: a.HCL},
config.Source{Name: a.Name + ".data_dir", Format: "hcl", Data: hclDataDir},
)
agent, err := New(a.Config, nil)
agent, err := New(a.Config, logger)
if err != nil {
panic(fmt.Sprintf("Error creating agent: %v", err))
}
a.Agent = agent
logOutput := a.LogOutput
if logOutput == nil {
logOutput = os.Stderr
}
agent.LogOutput = logOutput
agent.LogWriter = a.LogWriter
agent.logger = log.New(logOutput, a.Name+" - ", log.LstdFlags|log.Lmicroseconds)
agent.logger = logger
agent.MemSink = metrics.NewInmemSink(1*time.Second, time.Minute)
a.Agent.delegate = a
@ -156,7 +155,7 @@ func TestACL_Version8(t *testing.T) {
return nil, fmt.Errorf("should not have called delegate.ResolveToken")
}
a := NewTestACLAgent(t.Name(), TestACLConfig()+`
a := NewTestACLAgent(t, t.Name(), TestACLConfig()+`
acl_enforce_version_8 = false
`, resolveFn)
@ -171,7 +170,7 @@ func TestACL_Version8(t *testing.T) {
called = true
return nil, acl.ErrNotFound
}
a := NewTestACLAgent(t.Name(), TestACLConfig()+`
a := NewTestACLAgent(t, t.Name(), TestACLConfig()+`
acl_enforce_version_8 = true
`, resolveFn)
@ -189,7 +188,7 @@ func TestACL_AgentMasterToken(t *testing.T) {
return nil, fmt.Errorf("should not have called delegate.ResolveToken")
}
a := NewTestACLAgent(t.Name(), TestACLConfig(), resolveFn)
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), resolveFn)
a.loadTokens(a.config)
authz, err := a.resolveToken("towel")
require.NotNil(t, authz)
@ -209,7 +208,7 @@ func TestACL_RootAuthorizersDenied(t *testing.T) {
return nil, fmt.Errorf("should not have called delegate.ResolveToken")
}
a := NewTestACLAgent(t.Name(), TestACLConfig(), resolveFn)
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), resolveFn)
authz, err := a.resolveToken("deny")
require.Nil(t, authz)
require.Error(t, err)
@ -224,8 +223,8 @@ func TestACL_RootAuthorizersDenied(t *testing.T) {
require.True(t, acl.IsErrRootDenied(err))
}
func authzFromPolicy(policy *acl.Policy) (acl.Authorizer, error) {
return acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
func authzFromPolicy(policy *acl.Policy, cfg *acl.EnterpriseACLConfig) (acl.Authorizer, error) {
return acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, cfg)
}
// catalogPolicy supplies some standard policies to help with testing the
@ -240,7 +239,7 @@ func catalogPolicy(token string) (acl.Authorizer, error) {
&acl.NodeRule{Name: "Node", Policy: "read"},
},
},
})
}, nil)
case "node-rw":
return authzFromPolicy(&acl.Policy{
PolicyRules: acl.PolicyRules{
@ -248,7 +247,7 @@ func catalogPolicy(token string) (acl.Authorizer, error) {
&acl.NodeRule{Name: "Node", Policy: "write"},
},
},
})
}, nil)
case "service-ro":
return authzFromPolicy(&acl.Policy{
PolicyRules: acl.PolicyRules{
@ -256,7 +255,7 @@ func catalogPolicy(token string) (acl.Authorizer, error) {
&acl.ServiceRule{Name: "service", Policy: "read"},
},
},
})
}, nil)
case "service-rw":
return authzFromPolicy(&acl.Policy{
PolicyRules: acl.PolicyRules{
@ -264,7 +263,7 @@ func catalogPolicy(token string) (acl.Authorizer, error) {
&acl.ServiceRule{Name: "service", Policy: "write"},
},
},
})
}, nil)
case "other-rw":
return authzFromPolicy(&acl.Policy{
PolicyRules: acl.PolicyRules{
@ -272,7 +271,7 @@ func catalogPolicy(token string) (acl.Authorizer, error) {
&acl.ServiceRule{Name: "other", Policy: "write"},
},
},
})
}, nil)
default:
return nil, fmt.Errorf("unknown token %q", token)
}
@ -280,7 +279,7 @@ func catalogPolicy(token string) (acl.Authorizer, error) {
func TestACL_vetServiceRegister(t *testing.T) {
t.Parallel()
a := NewTestACLAgent(t.Name(), TestACLConfig(), catalogPolicy)
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy)
// Register a new service, with permission.
err := a.vetServiceRegister("service-rw", &structs.NodeService{
@ -311,7 +310,7 @@ func TestACL_vetServiceRegister(t *testing.T) {
func TestACL_vetServiceUpdate(t *testing.T) {
t.Parallel()
a := NewTestACLAgent(t.Name(), TestACLConfig(), catalogPolicy)
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy)
// Update a service that doesn't exist.
err := a.vetServiceUpdate("service-rw", "my-service")
@ -334,7 +333,7 @@ func TestACL_vetServiceUpdate(t *testing.T) {
func TestACL_vetCheckRegister(t *testing.T) {
t.Parallel()
a := NewTestACLAgent(t.Name(), TestACLConfig(), catalogPolicy)
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy)
// Register a new service check with write privs.
err := a.vetCheckRegister("service-rw", &structs.HealthCheck{
@ -400,7 +399,7 @@ func TestACL_vetCheckRegister(t *testing.T) {
func TestACL_vetCheckUpdate(t *testing.T) {
t.Parallel()
a := NewTestACLAgent(t.Name(), TestACLConfig(), catalogPolicy)
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy)
// Update a check that doesn't exist.
err := a.vetCheckUpdate("node-rw", "my-check")
@ -440,7 +439,7 @@ func TestACL_vetCheckUpdate(t *testing.T) {
func TestACL_filterMembers(t *testing.T) {
t.Parallel()
a := NewTestACLAgent(t.Name(), TestACLConfig(), catalogPolicy)
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy)
var members []serf.Member
require.NoError(t, a.filterMembers("node-ro", &members))
@ -459,7 +458,7 @@ func TestACL_filterMembers(t *testing.T) {
func TestACL_filterServices(t *testing.T) {
t.Parallel()
a := NewTestACLAgent(t.Name(), TestACLConfig(), catalogPolicy)
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy)
services := make(map[string]*structs.NodeService)
require.NoError(t, a.filterServices("node-ro", &services))
@ -473,7 +472,7 @@ func TestACL_filterServices(t *testing.T) {
func TestACL_filterChecks(t *testing.T) {
t.Parallel()
a := NewTestACLAgent(t.Name(), TestACLConfig(), catalogPolicy)
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy)
checks := make(map[types.CheckID]*structs.HealthCheck)
require.NoError(t, a.filterChecks("node-ro", &checks))

View File

@ -30,6 +30,7 @@ import (
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/logger"
"github.com/hashicorp/consul/sdk/testutil"
"github.com/hashicorp/consul/sdk/testutil/retry"
"github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/consul/types"
@ -1245,7 +1246,7 @@ func TestAgent_Reload(t *testing.T) {
t.Fatal("missing redis service")
}
cfg2 := TestConfig(config.Source{
cfg2 := TestConfig(testutil.TestLogger(t), config.Source{
Name: "reload",
Format: "hcl",
Data: `

View File

@ -3456,7 +3456,7 @@ func TestAgent_ReloadConfigOutgoingRPCConfig(t *testing.T) {
key_file = "../test/key/ourdomain.key"
verify_server_hostname = true
`
c := TestConfig(config.Source{Name: t.Name(), Format: "hcl", Data: hcl})
c := TestConfig(testutil.TestLogger(t), config.Source{Name: t.Name(), Format: "hcl", Data: hcl})
require.NoError(t, a.ReloadConfig(c))
tlsConf = a.tlsConfigurator.OutgoingRPCConfig()
require.False(t, tlsConf.InsecureSkipVerify)
@ -3495,7 +3495,7 @@ func TestAgent_ReloadConfigIncomingRPCConfig(t *testing.T) {
key_file = "../test/key/ourdomain.key"
verify_server_hostname = true
`
c := TestConfig(config.Source{Name: t.Name(), Format: "hcl", Data: hcl})
c := TestConfig(testutil.TestLogger(t), config.Source{Name: t.Name(), Format: "hcl", Data: hcl})
require.NoError(t, a.ReloadConfig(c))
tlsConf, err = tlsConf.GetConfigForClient(nil)
require.NoError(t, err)
@ -3524,7 +3524,7 @@ func TestAgent_ReloadConfigTLSConfigFailure(t *testing.T) {
data_dir = "` + dataDir + `"
verify_incoming = true
`
c := TestConfig(config.Source{Name: t.Name(), Format: "hcl", Data: hcl})
c := TestConfig(testutil.TestLogger(t), config.Source{Name: t.Name(), Format: "hcl", Data: hcl})
require.Error(t, a.ReloadConfig(c))
tlsConf, err := tlsConf.GetConfigForClient(nil)
require.NoError(t, err)

View File

@ -223,6 +223,10 @@ func NewACLResolver(config *ACLResolverConfig) (*ACLResolver, error) {
}, nil
}
func (r *ACLResolver) Close() {
r.entConf.Close()
}
func (r *ACLResolver) fetchAndCacheTokenLegacy(token string, cached *structs.AuthorizerCacheEntry) (acl.Authorizer, error) {
req := structs.ACLPolicyResolveLegacyRequest{
Datacenter: r.delegate.ACLDatacenter(true),
@ -1205,8 +1209,11 @@ func (f *aclFilter) filterSessions(sessions *structs.Sessions) {
s := *sessions
for i := 0; i < len(s); i++ {
session := s[i]
// TODO (namespaces) update to call with an actual ent authz context once sessions supports ns
if f.allowSession(session.Node, nil) {
var entCtx acl.EnterpriseAuthorizerContext
session.FillAuthzContext(&entCtx)
if f.allowSession(session.Node, &entCtx) {
continue
}
f.logger.Printf("[DEBUG] consul: dropping session %q from result due to ACLs", session.ID)

View File

@ -161,13 +161,12 @@ func (a *ACL) BootstrapTokens(args *structs.DCSpecificRequest, reply *structs.AC
CreateTime: time.Now(),
Local: false,
// DEPRECATED (ACL-Legacy-Compat) - This is used so that the bootstrap token is still visible via the v1 acl APIs
Type: structs.ACLTokenTypeManagement,
Type: structs.ACLTokenTypeManagement,
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
ResetIndex: specifiedIndex,
}
req.Token.EnterpriseMeta.InitDefault()
req.Token.SetHash(true)
resp, err := a.srv.raftApply(structs.ACLBootstrapRequestType, &req)

View File

@ -758,7 +758,7 @@ func TestACLReplication_AllTypes(t *testing.T) {
c.ACLsEnabled = true
c.ACLTokenReplication = true
c.ACLReplicationRate = 100
c.ACLReplicationBurst = 100
c.ACLReplicationBurst = 25
c.ACLReplicationApplyLimit = 1000000
})
s2.tokens.UpdateReplicationToken("root", tokenStore.TokenSourceConfig)

View File

@ -214,6 +214,9 @@ func (c *Client) Shutdown() error {
// Close the connection pool
c.connPool.Shutdown()
c.acls.Close()
return nil
}

View File

@ -505,18 +505,18 @@ func (s *Server) initializeACLs(upgrade bool) error {
}
if policy == nil || policy.Rules != structs.ACLPolicyGlobalManagement {
newPolicy := structs.ACLPolicy{
ID: structs.ACLPolicyGlobalManagementID,
Name: "global-management",
Description: "Builtin Policy that grants unlimited access",
Rules: structs.ACLPolicyGlobalManagement,
Syntax: acl.SyntaxCurrent,
ID: structs.ACLPolicyGlobalManagementID,
Name: "global-management",
Description: "Builtin Policy that grants unlimited access",
Rules: structs.ACLPolicyGlobalManagement,
Syntax: acl.SyntaxCurrent,
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
}
if policy != nil {
newPolicy.Name = policy.Name
newPolicy.Description = policy.Description
}
newPolicy.EnterpriseMeta.InitDefault()
newPolicy.SetHash(true)
req := structs.ACLPolicyBatchSetRequest{
@ -560,10 +560,10 @@ func (s *Server) initializeACLs(upgrade bool) error {
Local: false,
// DEPRECATED (ACL-Legacy-Compat) - only needed for compatibility
Type: structs.ACLTokenTypeManagement,
Type: structs.ACLTokenTypeManagement,
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
}
token.EnterpriseMeta.InitDefault()
token.SetHash(true)
done := false
@ -616,13 +616,13 @@ func (s *Server) initializeACLs(upgrade bool) error {
// the token upgrade routine will take care of upgrading the token if a legacy version exists
if legacyToken == nil {
token = &structs.ACLToken{
AccessorID: structs.ACLTokenAnonymousID,
SecretID: anonymousToken,
Description: "Anonymous Token",
CreateTime: time.Now(),
AccessorID: structs.ACLTokenAnonymousID,
SecretID: anonymousToken,
Description: "Anonymous Token",
CreateTime: time.Now(),
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
}
token.SetHash(true)
token.EnterpriseMeta.InitDefault()
req := structs.ACLTokenBatchSetRequest{
Tokens: structs.ACLTokens{token},

View File

@ -847,6 +847,8 @@ func (s *Server) Shutdown() error {
// Close the connection pool
s.connPool.Shutdown()
s.acls.Close()
if s.config.NotifyShutdown != nil {
s.config.NotifyShutdown()
}

View File

@ -230,7 +230,7 @@ func (s *Snapshot) ACLTokens() (memdb.ResultIterator, error) {
// ACLToken is used when restoring from a snapshot. For general inserts, use ACL.
func (s *Restore) ACLToken(token *structs.ACLToken) error {
return s.store.aclTokenInsert(s.tx, token, false)
return s.store.aclTokenInsert(s.tx, token)
}
// ACLPolicies is used when saving a snapshot
@ -243,7 +243,7 @@ func (s *Snapshot) ACLPolicies() (memdb.ResultIterator, error) {
}
func (s *Restore) ACLPolicy(policy *structs.ACLPolicy) error {
return s.store.aclPolicyInsert(s.tx, policy, false)
return s.store.aclPolicyInsert(s.tx, policy)
}
// ACLRoles is used when saving a snapshot
@ -256,7 +256,7 @@ func (s *Snapshot) ACLRoles() (memdb.ResultIterator, error) {
}
func (s *Restore) ACLRole(role *structs.ACLRole) error {
return s.store.aclRoleInsert(s.tx, role, false)
return s.store.aclRoleInsert(s.tx, role)
}
// ACLBindingRules is used when saving a snapshot
@ -269,7 +269,7 @@ func (s *Snapshot) ACLBindingRules() (memdb.ResultIterator, error) {
}
func (s *Restore) ACLBindingRule(rule *structs.ACLBindingRule) error {
return s.store.aclBindingRuleInsert(s.tx, rule, false)
return s.store.aclBindingRuleInsert(s.tx, rule)
}
// ACLAuthMethods is used when saving a snapshot
@ -282,7 +282,7 @@ func (s *Snapshot) ACLAuthMethods() (memdb.ResultIterator, error) {
}
func (s *Restore) ACLAuthMethod(method *structs.ACLAuthMethod) error {
return s.store.aclAuthMethodInsert(s.tx, method, false)
return s.store.aclAuthMethodInsert(s.tx, method)
}
// ACLBootstrap is used to perform a one-time ACL bootstrap operation on a
@ -765,7 +765,7 @@ func (s *Store) aclTokenSetTxn(tx *memdb.Txn, idx uint64, token *structs.ACLToke
token.ModifyIndex = idx
}
return s.aclTokenInsert(tx, token, true)
return s.aclTokenInsert(tx, token)
}
// ACLTokenGetBySecret is used to look up an existing ACL token by its SecretID.
@ -1163,7 +1163,7 @@ func (s *Store) aclPolicySetTxn(tx *memdb.Txn, idx uint64, policy *structs.ACLPo
}
// Insert the ACL
return s.aclPolicyInsert(tx, policy, true)
return s.aclPolicyInsert(tx, policy)
}
func (s *Store) ACLPolicyGetByID(ws memdb.WatchSet, id string, entMeta *structs.EnterpriseMeta) (uint64, *structs.ACLPolicy, error) {
@ -1379,7 +1379,7 @@ func (s *Store) aclRoleSetTxn(tx *memdb.Txn, idx uint64, role *structs.ACLRole,
role.ModifyIndex = idx
}
return s.aclRoleInsert(tx, role, true)
return s.aclRoleInsert(tx, role)
}
type aclRoleGetFn func(*memdb.Txn, string, *structs.EnterpriseMeta) (<-chan struct{}, interface{}, error)
@ -1588,7 +1588,7 @@ func (s *Store) aclBindingRuleSetTxn(tx *memdb.Txn, idx uint64, rule *structs.AC
return fmt.Errorf("failed inserting acl binding rule: auth method not found")
}
return s.aclBindingRuleInsert(tx, rule, true)
return s.aclBindingRuleInsert(tx, rule)
}
func (s *Store) ACLBindingRuleGetByID(ws memdb.WatchSet, id string, entMeta *structs.EnterpriseMeta) (uint64, *structs.ACLBindingRule, error) {
@ -1771,7 +1771,7 @@ func (s *Store) aclAuthMethodSetTxn(tx *memdb.Txn, idx uint64, method *structs.A
method.ModifyIndex = idx
}
return s.aclAuthMethodInsert(tx, method, true)
return s.aclAuthMethodInsert(tx, method)
}
func (s *Store) ACLAuthMethodGetByName(ws memdb.WatchSet, name string, entMeta *structs.EnterpriseMeta) (uint64, *structs.ACLAuthMethod, error) {

View File

@ -206,15 +206,13 @@ func authMethodsTableSchema() *memdb.TableSchema {
///// ACL Policy Functions /////
///////////////////////////////////////////////////////////////////////////////
func (s *Store) aclPolicyInsert(tx *memdb.Txn, policy *structs.ACLPolicy, updateIndexes bool) error {
func (s *Store) aclPolicyInsert(tx *memdb.Txn, policy *structs.ACLPolicy) error {
if err := tx.Insert("acl-policies", policy); err != nil {
return fmt.Errorf("failed inserting acl policy: %v", err)
}
if updateIndexes {
if err := tx.Insert("index", &IndexEntry{"acl-policies", policy.ModifyIndex}); err != nil {
return fmt.Errorf("failed updating acl policies index: %v", err)
}
if err := indexUpdateMaxTxn(tx, policy.ModifyIndex, "acl-policies"); err != nil {
return fmt.Errorf("failed updating acl policies index: %v", err)
}
return nil
@ -239,7 +237,7 @@ func (s *Store) aclPolicyDeleteWithPolicy(tx *memdb.Txn, policy *structs.ACLPoli
}
// update the overall acl-policies index
if err := tx.Insert("index", &IndexEntry{"acl-policies", idx}); err != nil {
if err := indexUpdateMaxTxn(tx, idx, "acl-policies"); err != nil {
return fmt.Errorf("failed updating acl policies index: %v", err)
}
return nil
@ -261,17 +259,15 @@ func (s *Store) ACLPolicyUpsertValidateEnterprise(*structs.ACLPolicy, *structs.A
///// ACL Token Functions /////
///////////////////////////////////////////////////////////////////////////////
func (s *Store) aclTokenInsert(tx *memdb.Txn, token *structs.ACLToken, updateIndexes bool) error {
func (s *Store) aclTokenInsert(tx *memdb.Txn, token *structs.ACLToken) error {
// insert the token into memdb
if err := tx.Insert("acl-tokens", token); err != nil {
return fmt.Errorf("failed inserting acl token: %v", err)
}
if updateIndexes {
// update the overall acl-tokens index
if err := tx.Insert("index", &IndexEntry{"acl-tokens", token.ModifyIndex}); err != nil {
return fmt.Errorf("failed updating acl tokens index: %v", err)
}
// update the overall acl-tokens index
if err := indexUpdateMaxTxn(tx, token.ModifyIndex, "acl-tokens"); err != nil {
return fmt.Errorf("failed updating acl tokens index: %v", err)
}
return nil
@ -312,7 +308,7 @@ func (s *Store) aclTokenDeleteWithToken(tx *memdb.Txn, token *structs.ACLToken,
}
// update the overall acl-tokens index
if err := tx.Insert("index", &IndexEntry{"acl-tokens", idx}); err != nil {
if err := indexUpdateMaxTxn(tx, idx, "acl-tokens"); err != nil {
return fmt.Errorf("failed updating acl tokens index: %v", err)
}
return nil
@ -334,17 +330,15 @@ func (s *Store) ACLTokenUpsertValidateEnterprise(token *structs.ACLToken, existi
///// ACL Role Functions /////
///////////////////////////////////////////////////////////////////////////////
func (s *Store) aclRoleInsert(tx *memdb.Txn, role *structs.ACLRole, updateIndexes bool) error {
func (s *Store) aclRoleInsert(tx *memdb.Txn, role *structs.ACLRole) error {
// insert the role into memdb
if err := tx.Insert("acl-roles", role); err != nil {
return fmt.Errorf("failed inserting acl role: %v", err)
}
if updateIndexes {
// update the overall acl-roles index
if err := tx.Insert("index", &IndexEntry{"acl-roles", role.ModifyIndex}); err != nil {
return fmt.Errorf("failed updating acl roles index: %v", err)
}
// update the overall acl-roles index
if err := indexUpdateMaxTxn(tx, role.ModifyIndex, "acl-roles"); err != nil {
return fmt.Errorf("failed updating acl roles index: %v", err)
}
return nil
}
@ -372,7 +366,7 @@ func (s *Store) aclRoleDeleteWithRole(tx *memdb.Txn, role *structs.ACLRole, idx
}
// update the overall acl-roles index
if err := tx.Insert("index", &IndexEntry{"acl-roles", idx}); err != nil {
if err := indexUpdateMaxTxn(tx, idx, "acl-roles"); err != nil {
return fmt.Errorf("failed updating acl policies index: %v", err)
}
return nil
@ -394,17 +388,15 @@ func (s *Store) ACLRoleUpsertValidateEnterprise(role *structs.ACLRole, existing
///// ACL Binding Rule Functions /////
///////////////////////////////////////////////////////////////////////////////
func (s *Store) aclBindingRuleInsert(tx *memdb.Txn, rule *structs.ACLBindingRule, updateIndexes bool) error {
func (s *Store) aclBindingRuleInsert(tx *memdb.Txn, rule *structs.ACLBindingRule) error {
// insert the role into memdb
if err := tx.Insert("acl-binding-rules", rule); err != nil {
return fmt.Errorf("failed inserting acl role: %v", err)
}
if updateIndexes {
// update the overall acl-binding-rules index
if err := tx.Insert("index", &IndexEntry{"acl-binding-rules", rule.ModifyIndex}); err != nil {
return fmt.Errorf("failed updating acl binding-rules index: %v", err)
}
// update the overall acl-binding-rules index
if err := indexUpdateMaxTxn(tx, rule.ModifyIndex, "acl-binding-rules"); err != nil {
return fmt.Errorf("failed updating acl binding-rules index: %v", err)
}
return nil
@ -429,7 +421,7 @@ func (s *Store) aclBindingRuleDeleteWithRule(tx *memdb.Txn, rule *structs.ACLBin
}
// update the overall acl-binding-rules index
if err := tx.Insert("index", &IndexEntry{"acl-binding-rules", idx}); err != nil {
if err := indexUpdateMaxTxn(tx, idx, "acl-binding-rules"); err != nil {
return fmt.Errorf("failed updating acl binding rules index: %v", err)
}
return nil
@ -451,17 +443,15 @@ func (s *Store) ACLBindingRuleUpsertValidateEnterprise(rule *structs.ACLBindingR
///// ACL Auth Method Functions /////
///////////////////////////////////////////////////////////////////////////////
func (s *Store) aclAuthMethodInsert(tx *memdb.Txn, method *structs.ACLAuthMethod, updateIndexes bool) error {
func (s *Store) aclAuthMethodInsert(tx *memdb.Txn, method *structs.ACLAuthMethod) error {
// insert the role into memdb
if err := tx.Insert("acl-auth-methods", method); err != nil {
return fmt.Errorf("failed inserting acl role: %v", err)
}
if updateIndexes {
// update the overall acl-auth-methods index
if err := tx.Insert("index", &IndexEntry{"acl-auth-methods", method.ModifyIndex}); err != nil {
return fmt.Errorf("failed updating acl auth methods index: %v", err)
}
// update the overall acl-auth-methods index
if err := indexUpdateMaxTxn(tx, method.ModifyIndex, "acl-auth-methods"); err != nil {
return fmt.Errorf("failed updating acl auth methods index: %v", err)
}
return nil
@ -482,7 +472,7 @@ func (s *Store) aclAuthMethodDeleteWithMethod(tx *memdb.Txn, method *structs.ACL
}
// update the overall acl-auth-methods index
if err := tx.Insert("index", &IndexEntry{"acl-auth-methods", idx}); err != nil {
if err := indexUpdateMaxTxn(tx, idx, "acl-auth-methods"); err != nil {
return fmt.Errorf("failed updating acl auth methods index: %v", err)
}
return nil

View File

@ -20,6 +20,10 @@ func (s *HTTPServer) parseEntMeta(req *http.Request, entMeta *structs.Enterprise
return nil
}
func (s *HTTPServer) parseEntMetaNoWildcard(req *http.Request, _ *structs.EnterpriseMeta) error {
return s.parseEntMeta(req, nil)
}
func (s *HTTPServer) rewordUnknownEnterpriseFieldError(err error) error {
if err == nil {
return nil

View File

@ -452,7 +452,7 @@ func (t *ACLToken) SetHash(force bool) []byte {
srvid.AddToHash(hash)
}
t.EnterpriseMeta.addToHash(hash)
t.EnterpriseMeta.addToHash(hash, false)
// Finalize the hash
hashVal := hash.Sum(nil)
@ -645,7 +645,7 @@ func (p *ACLPolicy) SetHash(force bool) []byte {
hash.Write([]byte(dc))
}
p.EnterpriseMeta.addToHash(hash)
p.EnterpriseMeta.addToHash(hash, false)
// Finalize the hash
hashVal := hash.Sum(nil)
@ -879,7 +879,7 @@ func (r *ACLRole) SetHash(force bool) []byte {
srvid.AddToHash(hash)
}
r.EnterpriseMeta.addToHash(hash)
r.EnterpriseMeta.addToHash(hash, false)
// Finalize the hash
hashVal := hash.Sum(nil)

View File

@ -8,6 +8,8 @@ import (
"github.com/hashicorp/consul/acl"
)
var emptyEnterpriseMeta = EnterpriseMeta{}
// EnterpriseMeta stub
type EnterpriseMeta struct{}
@ -15,30 +17,27 @@ func (m *EnterpriseMeta) estimateSize() int {
return 0
}
func (m *EnterpriseMeta) addToHash(hasher hash.Hash) {
func (m *EnterpriseMeta) addToHash(_ hash.Hash, _ bool) {
// do nothing
}
// WildcardEnterpriseMeta stub
func WildcardEnterpriseMeta() *EnterpriseMeta {
return nil
}
// ReplicationEnterpriseMeta stub
func ReplicationEnterpriseMeta() *EnterpriseMeta {
return nil
return &emptyEnterpriseMeta
}
// DefaultEnterpriseMeta stub
func DefaultEnterpriseMeta() *EnterpriseMeta {
return nil
return &emptyEnterpriseMeta
}
// InitDefault stub
func (m *EnterpriseMeta) InitDefault() {}
// WildcardEnterpriseMeta stub
func WildcardEnterpriseMeta() *EnterpriseMeta {
return &emptyEnterpriseMeta
}
// FillAuthzContext stub
func (m *EnterpriseMeta) FillAuthzContext(*acl.EnterpriseAuthorizerContext) {}
func (_ *EnterpriseMeta) FillAuthzContext(_ *acl.EnterpriseAuthorizerContext) {}
// FillAuthzContext stub
func (d *DirEntry) FillAuthzContext(*acl.EnterpriseAuthorizerContext) {}

View File

@ -156,9 +156,15 @@ func (a *TestAgent) Start() (err error) {
hclDataDir = `data_dir = "` + d + `"`
}
logOutput := a.LogOutput
if logOutput == nil {
logOutput = os.Stderr
}
agentLogger := log.New(logOutput, a.Name+" - ", log.LstdFlags|log.Lmicroseconds)
portsConfig, returnPortsFn := randomPortsSource(a.UseTLS)
a.returnPortsFn = returnPortsFn
a.Config = TestConfig(
a.Config = TestConfig(agentLogger,
portsConfig,
config.Source{Name: a.Name, Format: "hcl", Data: a.HCL},
config.Source{Name: a.Name + ".data_dir", Format: "hcl", Data: hclDataDir},
@ -191,12 +197,6 @@ func (a *TestAgent) Start() (err error) {
}
}
logOutput := a.LogOutput
if logOutput == nil {
logOutput = os.Stderr
}
agentLogger := log.New(logOutput, a.Name+" - ", log.LstdFlags|log.Lmicroseconds)
agent, err := New(a.Config, agentLogger)
if err != nil {
cleanupTmpDir()
@ -411,7 +411,7 @@ func NodeID() string {
// TestConfig returns a unique default configuration for testing an
// agent.
func TestConfig(sources ...config.Source) *config.RuntimeConfig {
func TestConfig(logger *log.Logger, sources ...config.Source) *config.RuntimeConfig {
nodeID := NodeID()
testsrc := config.Source{
Name: "test",
@ -450,7 +450,7 @@ func TestConfig(sources ...config.Source) *config.RuntimeConfig {
}
for _, w := range b.Warnings {
fmt.Println("WARNING:", w)
logger.Printf("[WARN] %s", w)
}
// Effectively disables the delay after root rotation before requesting CSRs

View File

@ -5,4 +5,5 @@ package sentinel
type Evaluator interface {
Compile(policy string) error
Execute(policy string, enforcementLevel string, data map[string]interface{}) bool
Close()
}

View File

@ -12,6 +12,8 @@ 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) {
t.Helper()
var out structs.IndexedNodes
retry.Run(t, func(r *retry.R) {
args := &structs.DCSpecificRequest{Datacenter: dc}
@ -29,6 +31,8 @@ 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) {
t.Helper()
var out structs.IndexedNodes
retry.Run(t, func(r *retry.R) {
args := &structs.DCSpecificRequest{Datacenter: dc}
@ -56,6 +60,8 @@ func WaitForAntiEntropySync() waitOption {
// WaitForTestAgent ensures we have a node with serfHealth check registered
func WaitForTestAgent(t *testing.T, rpc rpcFn, dc string, options ...waitOption) {
t.Helper()
var nodes structs.IndexedNodes
var checks structs.IndexedHealthChecks