3dd0b59793
* hclog Allow users to choose between unstructured and JSON logging
133 lines
3.9 KiB
Go
133 lines
3.9 KiB
Go
package consul
|
|
|
|
import (
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"github.com/hashicorp/consul/acl"
|
|
"github.com/hashicorp/consul/agent/metadata"
|
|
"github.com/hashicorp/consul/agent/structs"
|
|
"github.com/hashicorp/consul/lib"
|
|
"github.com/hashicorp/serf/serf"
|
|
)
|
|
|
|
var clientACLCacheConfig *structs.ACLCachesConfig = &structs.ACLCachesConfig{
|
|
// The ACL cache configuration on client agents is more conservative than
|
|
// on the servers. It is assumed that individual client agents will have
|
|
// fewer distinct identities accessing the client than a server would
|
|
// and thus can put smaller limits on the amount of ACL caching done.
|
|
//
|
|
// Identities - number of identities/acl tokens that can be cached
|
|
Identities: 1024,
|
|
// Policies - number of unparsed ACL policies that can be cached
|
|
Policies: 128,
|
|
// ParsedPolicies - number of parsed ACL policies that can be cached
|
|
ParsedPolicies: 128,
|
|
// Authorizers - number of compiled multi-policy effective policies that can be cached
|
|
Authorizers: 256,
|
|
// Roles - number of ACL roles that can be cached
|
|
Roles: 128,
|
|
}
|
|
|
|
func (c *Client) UseLegacyACLs() bool {
|
|
return atomic.LoadInt32(&c.useNewACLs) == 0
|
|
}
|
|
|
|
func (c *Client) monitorACLMode() {
|
|
waitTime := aclModeCheckMinInterval
|
|
for {
|
|
canUpgrade := false
|
|
for _, member := range c.LANMembers() {
|
|
if valid, parts := metadata.IsConsulServer(member); valid && parts.Status == serf.StatusAlive {
|
|
if parts.ACLs != structs.ACLModeEnabled {
|
|
canUpgrade = false
|
|
break
|
|
} else {
|
|
canUpgrade = true
|
|
}
|
|
}
|
|
}
|
|
|
|
if canUpgrade {
|
|
c.logger.Debug("transitioned out of legacy ACL mode")
|
|
atomic.StoreInt32(&c.useNewACLs, 1)
|
|
lib.UpdateSerfTag(c.serf, "acls", string(structs.ACLModeEnabled))
|
|
return
|
|
}
|
|
|
|
select {
|
|
case <-c.shutdownCh:
|
|
return
|
|
case <-time.After(waitTime):
|
|
// do nothing
|
|
}
|
|
|
|
// calculate the amount of time to wait for the next round
|
|
waitTime = waitTime * 2
|
|
if waitTime > aclModeCheckMaxInterval {
|
|
waitTime = aclModeCheckMaxInterval
|
|
}
|
|
}
|
|
}
|
|
|
|
func (c *Client) ACLDatacenter(legacy bool) string {
|
|
// For resolution running on clients, when not in
|
|
// legacy mode the servers within the current datacenter
|
|
// must be queried first to pick up local tokens. When
|
|
// in legacy mode the clients should directly query the
|
|
// ACL Datacenter. When no ACL datacenter has been set
|
|
// then we assume that the local DC is the ACL DC
|
|
if legacy && c.config.ACLDatacenter != "" {
|
|
return c.config.ACLDatacenter
|
|
}
|
|
|
|
return c.config.Datacenter
|
|
}
|
|
|
|
func (c *Client) ACLsEnabled() bool {
|
|
return c.config.ACLsEnabled
|
|
}
|
|
|
|
func (c *Client) ResolveIdentityFromToken(token string) (bool, structs.ACLIdentity, error) {
|
|
// clients do no local identity resolution at the moment
|
|
return false, nil, nil
|
|
}
|
|
|
|
func (c *Client) ResolvePolicyFromID(policyID string) (bool, *structs.ACLPolicy, error) {
|
|
// clients do no local policy resolution at the moment
|
|
return false, nil, nil
|
|
}
|
|
|
|
func (c *Client) ResolveRoleFromID(roleID string) (bool, *structs.ACLRole, error) {
|
|
// clients do no local role resolution at the moment
|
|
return false, nil, nil
|
|
}
|
|
|
|
func (c *Client) ResolveToken(token string) (acl.Authorizer, error) {
|
|
return c.acls.ResolveToken(token)
|
|
}
|
|
|
|
func (c *Client) ResolveTokenToIdentityAndAuthorizer(token string) (structs.ACLIdentity, acl.Authorizer, error) {
|
|
return c.acls.ResolveTokenToIdentityAndAuthorizer(token)
|
|
}
|
|
|
|
func (c *Client) ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) {
|
|
identity, authz, err := c.acls.ResolveTokenToIdentityAndAuthorizer(token)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Default the EnterpriseMeta based on the Tokens meta or actual defaults
|
|
// in the case of unknown identity
|
|
if identity != nil {
|
|
entMeta.Merge(identity.EnterpriseMetadata())
|
|
} else {
|
|
entMeta.Merge(structs.DefaultEnterpriseMeta())
|
|
}
|
|
|
|
// Use the meta to fill in the ACL authorization context
|
|
entMeta.FillAuthzContext(authzContext)
|
|
|
|
return authz, err
|
|
}
|