consul/agent/structs/acl_cache.go
hashicorp-copywrite[bot] 5fb9df1640
[COMPLIANCE] License changes (#18443)
* Adding explicit MPL license for sub-package

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Adding explicit MPL license for sub-package

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Updating the license from MPL to Business Source License

Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at <Blog URL>, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl.

* add missing license headers

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

---------

Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
2023-08-11 09:12:13 -04:00

296 lines
6.4 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package structs
import (
"time"
lru "github.com/hashicorp/golang-lru"
"github.com/hashicorp/consul/acl"
)
type ACLCachesConfig struct {
Identities int
Policies int
ParsedPolicies int
Authorizers int
Roles int
}
type ACLCaches struct {
identities *lru.TwoQueueCache // identity id -> structs.ACLIdentity
parsedPolicies *lru.TwoQueueCache // policy content hash -> acl.Policy
policies *lru.TwoQueueCache // policy ID -> ACLPolicy
authorizers *lru.TwoQueueCache // token secret -> acl.Authorizer
roles *lru.TwoQueueCache // role ID -> ACLRole
}
type IdentityCacheEntry struct {
Identity ACLIdentity
CacheTime time.Time
}
func (e *IdentityCacheEntry) Age() time.Duration {
return time.Since(e.CacheTime)
}
type ParsedPolicyCacheEntry struct {
Policy *acl.Policy
CacheTime time.Time
}
func (e *ParsedPolicyCacheEntry) Age() time.Duration {
return time.Since(e.CacheTime)
}
type PolicyCacheEntry struct {
Policy *ACLPolicy
CacheTime time.Time
}
func (e *PolicyCacheEntry) Age() time.Duration {
return time.Since(e.CacheTime)
}
type AuthorizerCacheEntry struct {
Authorizer acl.Authorizer
CacheTime time.Time
TTL time.Duration
}
func (e *AuthorizerCacheEntry) Age() time.Duration {
return time.Since(e.CacheTime)
}
type RoleCacheEntry struct {
Role *ACLRole
CacheTime time.Time
}
func (e *RoleCacheEntry) Age() time.Duration {
return time.Since(e.CacheTime)
}
func NewACLCaches(config *ACLCachesConfig) (*ACLCaches, error) {
cache := &ACLCaches{}
if config != nil && config.Identities > 0 {
identCache, err := lru.New2Q(config.Identities)
if err != nil {
return nil, err
}
cache.identities = identCache
}
if config != nil && config.Policies > 0 {
policyCache, err := lru.New2Q(config.Policies)
if err != nil {
return nil, err
}
cache.policies = policyCache
}
if config != nil && config.ParsedPolicies > 0 {
parsedCache, err := lru.New2Q(config.ParsedPolicies)
if err != nil {
return nil, err
}
cache.parsedPolicies = parsedCache
}
if config != nil && config.Authorizers > 0 {
authCache, err := lru.New2Q(config.Authorizers)
if err != nil {
return nil, err
}
cache.authorizers = authCache
}
if config != nil && config.Roles > 0 {
roleCache, err := lru.New2Q(config.Roles)
if err != nil {
return nil, err
}
cache.roles = roleCache
}
return cache, nil
}
// GetIdentity fetches an identity from the cache and returns it
func (c *ACLCaches) GetIdentity(id string) *IdentityCacheEntry {
if c == nil || c.identities == nil {
return nil
}
if raw, ok := c.identities.Get(id); ok {
return raw.(*IdentityCacheEntry)
}
return nil
}
// GetIdentityWithSecretToken fetches the identity with the given secret token
// from the cache.
func (c *ACLCaches) GetIdentityWithSecretToken(secretToken string) *IdentityCacheEntry {
return c.GetIdentity(cacheIDSecretToken(secretToken))
}
// GetPolicy fetches a policy from the cache and returns it
func (c *ACLCaches) GetPolicy(policyID string) *PolicyCacheEntry {
if c == nil || c.policies == nil {
return nil
}
if raw, ok := c.policies.Get(policyID); ok {
return raw.(*PolicyCacheEntry)
}
return nil
}
// GetPolicy fetches a policy from the cache and returns it
func (c *ACLCaches) GetParsedPolicy(id string) *ParsedPolicyCacheEntry {
if c == nil || c.parsedPolicies == nil {
return nil
}
if raw, ok := c.parsedPolicies.Get(id); ok {
return raw.(*ParsedPolicyCacheEntry)
}
return nil
}
// GetAuthorizer fetches a acl from the cache and returns it
func (c *ACLCaches) GetAuthorizer(id string) *AuthorizerCacheEntry {
if c == nil || c.authorizers == nil {
return nil
}
if raw, ok := c.authorizers.Get(id); ok {
return raw.(*AuthorizerCacheEntry)
}
return nil
}
// GetRole fetches a role from the cache by id and returns it
func (c *ACLCaches) GetRole(roleID string) *RoleCacheEntry {
if c == nil || c.roles == nil {
return nil
}
if raw, ok := c.roles.Get(roleID); ok {
return raw.(*RoleCacheEntry)
}
return nil
}
// PutIdentity adds a new identity to the cache
func (c *ACLCaches) PutIdentity(id string, ident ACLIdentity) {
if c == nil || c.identities == nil {
return
}
c.identities.Add(id, &IdentityCacheEntry{Identity: ident, CacheTime: time.Now()})
}
// PutIdentityWithSecretToken adds a new identity to the cache, keyed by the
// given secret token (with a prefix to prevent collisions).
func (c *ACLCaches) PutIdentityWithSecretToken(secretToken string, identity ACLIdentity) {
c.PutIdentity(cacheIDSecretToken(secretToken), identity)
}
// RemoveIdentityWithSecretToken removes the identity from the cache with the
// given secret token.
func (c *ACLCaches) RemoveIdentityWithSecretToken(secretToken string) {
if c == nil || c.identities == nil {
return
}
c.identities.Remove(cacheIDSecretToken(secretToken))
}
func (c *ACLCaches) PutPolicy(policyId string, policy *ACLPolicy) {
if c == nil || c.policies == nil {
return
}
c.policies.Add(policyId, &PolicyCacheEntry{Policy: policy, CacheTime: time.Now()})
}
func (c *ACLCaches) PutParsedPolicy(id string, policy *acl.Policy) {
if c == nil || c.parsedPolicies == nil {
return
}
c.parsedPolicies.Add(id, &ParsedPolicyCacheEntry{Policy: policy, CacheTime: time.Now()})
}
func (c *ACLCaches) PutAuthorizer(id string, authorizer acl.Authorizer) {
if c == nil || c.authorizers == nil {
return
}
c.authorizers.Add(id, &AuthorizerCacheEntry{Authorizer: authorizer, CacheTime: time.Now()})
}
func (c *ACLCaches) PutRole(roleID string, role *ACLRole) {
if c == nil || c.roles == nil {
return
}
c.roles.Add(roleID, &RoleCacheEntry{Role: role, CacheTime: time.Now()})
}
func (c *ACLCaches) RemoveIdentity(id string) {
if c != nil && c.identities != nil {
c.identities.Remove(id)
}
}
func (c *ACLCaches) RemovePolicy(policyID string) {
if c != nil && c.policies != nil {
c.policies.Remove(policyID)
}
}
func (c *ACLCaches) RemoveRole(roleID string) {
if c != nil && c.roles != nil {
c.roles.Remove(roleID)
}
}
func (c *ACLCaches) Purge() {
if c != nil {
if c.identities != nil {
c.identities.Purge()
}
if c.policies != nil {
c.policies.Purge()
}
if c.parsedPolicies != nil {
c.parsedPolicies.Purge()
}
if c.authorizers != nil {
c.authorizers.Purge()
}
if c.roles != nil {
c.roles.Purge()
}
}
}
func cacheIDSecretToken(token string) string {
return "token-secret:" + token
}