1package structs 2 3import ( 4 "time" 5 6 "github.com/hashicorp/consul/acl" 7 lru "github.com/hashicorp/golang-lru" 8) 9 10type ACLCachesConfig struct { 11 Identities int 12 Policies int 13 ParsedPolicies int 14 Authorizers int 15 Roles int 16} 17 18type ACLCaches struct { 19 identities *lru.TwoQueueCache // identity id -> structs.ACLIdentity 20 parsedPolicies *lru.TwoQueueCache // policy content hash -> acl.Policy 21 policies *lru.TwoQueueCache // policy ID -> ACLPolicy 22 authorizers *lru.TwoQueueCache // token secret -> acl.Authorizer 23 roles *lru.TwoQueueCache // role ID -> ACLRole 24} 25 26type IdentityCacheEntry struct { 27 Identity ACLIdentity 28 CacheTime time.Time 29} 30 31func (e *IdentityCacheEntry) Age() time.Duration { 32 return time.Since(e.CacheTime) 33} 34 35type ParsedPolicyCacheEntry struct { 36 Policy *acl.Policy 37 CacheTime time.Time 38} 39 40func (e *ParsedPolicyCacheEntry) Age() time.Duration { 41 return time.Since(e.CacheTime) 42} 43 44type PolicyCacheEntry struct { 45 Policy *ACLPolicy 46 CacheTime time.Time 47} 48 49func (e *PolicyCacheEntry) Age() time.Duration { 50 return time.Since(e.CacheTime) 51} 52 53type AuthorizerCacheEntry struct { 54 Authorizer acl.Authorizer 55 CacheTime time.Time 56 TTL time.Duration 57} 58 59func (e *AuthorizerCacheEntry) Age() time.Duration { 60 return time.Since(e.CacheTime) 61} 62 63type RoleCacheEntry struct { 64 Role *ACLRole 65 CacheTime time.Time 66} 67 68func (e *RoleCacheEntry) Age() time.Duration { 69 return time.Since(e.CacheTime) 70} 71 72func NewACLCaches(config *ACLCachesConfig) (*ACLCaches, error) { 73 cache := &ACLCaches{} 74 75 if config != nil && config.Identities > 0 { 76 identCache, err := lru.New2Q(config.Identities) 77 if err != nil { 78 return nil, err 79 } 80 81 cache.identities = identCache 82 } 83 84 if config != nil && config.Policies > 0 { 85 policyCache, err := lru.New2Q(config.Policies) 86 if err != nil { 87 return nil, err 88 } 89 90 cache.policies = policyCache 91 } 92 93 if config != nil && config.ParsedPolicies > 0 { 94 parsedCache, err := lru.New2Q(config.ParsedPolicies) 95 if err != nil { 96 return nil, err 97 } 98 99 cache.parsedPolicies = parsedCache 100 } 101 102 if config != nil && config.Authorizers > 0 { 103 authCache, err := lru.New2Q(config.Authorizers) 104 if err != nil { 105 return nil, err 106 } 107 108 cache.authorizers = authCache 109 } 110 111 if config != nil && config.Roles > 0 { 112 roleCache, err := lru.New2Q(config.Roles) 113 if err != nil { 114 return nil, err 115 } 116 117 cache.roles = roleCache 118 } 119 120 return cache, nil 121} 122 123// GetIdentity fetches an identity from the cache and returns it 124func (c *ACLCaches) GetIdentity(id string) *IdentityCacheEntry { 125 if c == nil || c.identities == nil { 126 return nil 127 } 128 129 if raw, ok := c.identities.Get(id); ok { 130 return raw.(*IdentityCacheEntry) 131 } 132 133 return nil 134} 135 136// GetPolicy fetches a policy from the cache and returns it 137func (c *ACLCaches) GetPolicy(policyID string) *PolicyCacheEntry { 138 if c == nil || c.policies == nil { 139 return nil 140 } 141 142 if raw, ok := c.policies.Get(policyID); ok { 143 return raw.(*PolicyCacheEntry) 144 } 145 146 return nil 147} 148 149// GetPolicy fetches a policy from the cache and returns it 150func (c *ACLCaches) GetParsedPolicy(id string) *ParsedPolicyCacheEntry { 151 if c == nil || c.parsedPolicies == nil { 152 return nil 153 } 154 155 if raw, ok := c.parsedPolicies.Get(id); ok { 156 return raw.(*ParsedPolicyCacheEntry) 157 } 158 159 return nil 160} 161 162// GetAuthorizer fetches a acl from the cache and returns it 163func (c *ACLCaches) GetAuthorizer(id string) *AuthorizerCacheEntry { 164 if c == nil || c.authorizers == nil { 165 return nil 166 } 167 168 if raw, ok := c.authorizers.Get(id); ok { 169 return raw.(*AuthorizerCacheEntry) 170 } 171 172 return nil 173} 174 175// GetRole fetches a role from the cache by id and returns it 176func (c *ACLCaches) GetRole(roleID string) *RoleCacheEntry { 177 if c == nil || c.roles == nil { 178 return nil 179 } 180 181 if raw, ok := c.roles.Get(roleID); ok { 182 return raw.(*RoleCacheEntry) 183 } 184 185 return nil 186} 187 188// PutIdentity adds a new identity to the cache 189func (c *ACLCaches) PutIdentity(id string, ident ACLIdentity) { 190 if c == nil || c.identities == nil { 191 return 192 } 193 194 c.identities.Add(id, &IdentityCacheEntry{Identity: ident, CacheTime: time.Now()}) 195} 196 197func (c *ACLCaches) PutPolicy(policyId string, policy *ACLPolicy) { 198 if c == nil || c.policies == nil { 199 return 200 } 201 202 c.policies.Add(policyId, &PolicyCacheEntry{Policy: policy, CacheTime: time.Now()}) 203} 204 205func (c *ACLCaches) PutParsedPolicy(id string, policy *acl.Policy) { 206 if c == nil || c.parsedPolicies == nil { 207 return 208 } 209 210 c.parsedPolicies.Add(id, &ParsedPolicyCacheEntry{Policy: policy, CacheTime: time.Now()}) 211} 212 213func (c *ACLCaches) PutAuthorizer(id string, authorizer acl.Authorizer) { 214 if c == nil || c.authorizers == nil { 215 return 216 } 217 218 c.authorizers.Add(id, &AuthorizerCacheEntry{Authorizer: authorizer, CacheTime: time.Now()}) 219} 220 221func (c *ACLCaches) PutAuthorizerWithTTL(id string, authorizer acl.Authorizer, ttl time.Duration) { 222 if c == nil || c.authorizers == nil { 223 return 224 } 225 226 c.authorizers.Add(id, &AuthorizerCacheEntry{Authorizer: authorizer, CacheTime: time.Now(), TTL: ttl}) 227} 228 229func (c *ACLCaches) PutRole(roleID string, role *ACLRole) { 230 if c == nil || c.roles == nil { 231 return 232 } 233 234 c.roles.Add(roleID, &RoleCacheEntry{Role: role, CacheTime: time.Now()}) 235} 236 237func (c *ACLCaches) RemoveIdentity(id string) { 238 if c != nil && c.identities != nil { 239 c.identities.Remove(id) 240 } 241} 242 243func (c *ACLCaches) RemovePolicy(policyID string) { 244 if c != nil && c.policies != nil { 245 c.policies.Remove(policyID) 246 } 247} 248 249func (c *ACLCaches) RemoveRole(roleID string) { 250 if c != nil && c.roles != nil { 251 c.roles.Remove(roleID) 252 } 253} 254 255func (c *ACLCaches) Purge() { 256 if c != nil { 257 if c.identities != nil { 258 c.identities.Purge() 259 } 260 if c.policies != nil { 261 c.policies.Purge() 262 } 263 if c.parsedPolicies != nil { 264 c.parsedPolicies.Purge() 265 } 266 if c.authorizers != nil { 267 c.authorizers.Purge() 268 } 269 if c.roles != nil { 270 c.roles.Purge() 271 } 272 } 273} 274