Class: Cache
- Inherits:
-
Object
- Object
- Cache
- Defined in:
- lib/puppet/functions/hiera_vault.rb
Overview
Cache will keep track of all the results gotten from the Vault server. To avoid leaking secrets both the key looked for and the options are used as the key for the cache so that using the same key with different options will not risk leaking a secret. To keep things fast and not have the pruning method take longer as the number of entries grow we create a Hash for each value of cache_for and keep entries in this hash ordered from the oldest one to the most recent. When looking for entries to evict we iterate over each Hash in order and stop when we find the first entry that we must keep: because all the subsequent entries will be younger there is no need to continue as we will need to keep them all. Doing this make time spent pruning the cache proportional to number of entries that actually need to be evicted, and not to the total number of entries in the cache. We avoid keeping secrets in memory for longer than necessary by calling prune before each operation of the cache, we always evict secret from memory as soon as we can. Note that we don’t need synchronization primitives in Cache because we always hold hiera_vault_mutex when accessing the cache.
Defined Under Namespace
Classes: CacheKey, CacheValue
Instance Method Summary collapse
- #get(key, options) ⇒ Object
-
#initialize ⇒ Cache
constructor
A new instance of Cache.
-
#prune ⇒ Object
Removes all the expired entries from the cache.
- #set(key, value, options) ⇒ Object
Constructor Details
#initialize ⇒ Cache
Returns a new instance of Cache.
23 24 25 |
# File 'lib/puppet/functions/hiera_vault.rb', line 23 def initialize @caches = Hash.new { |hash, key| hash[key] = {} } end |
Instance Method Details
#get(key, options) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/puppet/functions/hiera_vault.rb', line 45 def get(key, ) prune cache_for = ['cache_for'] # Early exit if the cache is deactivated return nil if cache_for.nil? k = CacheKey.new(key, ) cache = @caches[cache_for] # We don't need to check whether the value has expired because it would # have been removed during prune cache[k] end |
#prune ⇒ Object
Removes all the expired entries from the cache
62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/puppet/functions/hiera_vault.rb', line 62 def prune @caches.each_value do |cache| cache.each do |key, value| # Because the entries in each cache are ordered we can stop as soon as # we find one that we need to keep, all the following ones will be # younger and need to be kept too break if value.until >= Time.now cache.delete(key) end end end |
#set(key, value, options) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/puppet/functions/hiera_vault.rb', line 27 def set(key, value, ) prune cache_for = ['cache_for'] # Early exit if the cache is deactivated return nil if cache_for.nil? k = CacheKey.new(key, ) cache = @caches[cache_for] # We first delete the key from the cache so it will always be ordered from # oldest entries to most recent cache.delete(k) cache[k] = CacheValue.new(value, Time.now + cache_for) end |