The class that connects functional classes with their different collection back-ends. Each indirection has a set of associated terminus classes, each of which is a subclass of Puppet::Indirector::Terminus.
This can be used to select the terminus class.
Find an indirection by name. This is provided so that Terminus classes can specifically hook up with the indirections they are associated with.
# File lib/puppet/indirector/indirection.rb, line 27 def self.instance(name) @@indirections.find { |i| i.name == name } end
Return a list of all known indirections. Used to generate the reference.
# File lib/puppet/indirector/indirection.rb, line 33 def self.instances @@indirections.collect { |i| i.name } end
Find an indirected model by name. This is provided so that Terminus classes can specifically hook up with the indirections they are associated with.
# File lib/puppet/indirector/indirection.rb, line 39 def self.model(name) return nil unless match = @@indirections.find { |i| i.name == name } match.model end
# File lib/puppet/indirector/indirection.rb, line 96 def initialize(model, name, options = {}) @model = model @name = name @termini = {} @cache_class = nil @terminus_class = nil raise(ArgumentError, "Indirection #{@name} is already defined") if @@indirections.find { |i| i.name == @name } @@indirections << self if mod = options[:extend] extend(mod) options.delete(:extend) end # This is currently only used for cache_class and terminus_class. set_options(options) end
Create and return our cache terminus.
# File lib/puppet/indirector/indirection.rb, line 45 def cache raise(Puppet::DevError, "Tried to cache when no cache class was set") unless cache_class terminus(cache_class) end
Should we use a cache?
# File lib/puppet/indirector/indirection.rb, line 51 def cache? cache_class ? true : false end
Define a terminus class to be used for caching.
# File lib/puppet/indirector/indirection.rb, line 57 def cache_class=(class_name) validate_terminus_class(class_name) if class_name @cache_class = class_name end
This is only used for testing.
# File lib/puppet/indirector/indirection.rb, line 63 def delete @@indirections.delete(self) if @@indirections.include?(self) end
Remove something via the terminus.
# File lib/puppet/indirector/indirection.rb, line 231 def destroy(key, options={}) request = request(:destroy, key, nil, options) terminus = prepare(request) result = terminus.destroy(request) if cache? and cached = cache.find(request(:find, key, nil, options)) # Reuse the existing request, since it's equivalent. cache.destroy(request) end result end
Generate the full doc string.
# File lib/puppet/indirector/indirection.rb, line 84 def doc text = "" text += scrub(@doc) + "\n\n" if @doc if s = terminus_setting text += "* **Terminus Setting**: #{terminus_setting}" end text end
Calculate the expiration date for a returned instance.
# File lib/puppet/indirector/indirection.rb, line 79 def expiration Time.now + ttl end
Expire a cached object, if one is cached. Note that we don’t actually remove it, we expire it and write it back out to disk. This way people can still use the expired object if they want.
# File lib/puppet/indirector/indirection.rb, line 165 def expire(key, options={}) request = request(:expire, key, nil, options) return nil unless cache? return nil unless instance = cache.find(request(:find, key, nil, options)) Puppet.info "Expiring the #{self.name} cache of #{instance.name}" # Set an expiration date in the past instance.expiration = Time.now - 60 cache.save(request(:save, nil, instance, options)) end
Search for an instance in the appropriate terminus, caching the results if caching is configured..
# File lib/puppet/indirector/indirection.rb, line 182 def find(key, options={}) request = request(:find, key, nil, options) terminus = prepare(request) if result = find_in_cache(request) return result end # Otherwise, return the result from the terminus, caching if appropriate. if ! request.ignore_terminus? and result = terminus.find(request) result.expiration ||= self.expiration if result.respond_to?(:expiration) if cache? and request.use_cache? Puppet.info "Caching #{self.name} for #{request.key}" cache.save request(:save, key, result, options) end return terminus.respond_to?(:filter) ? terminus.filter(result) : result end nil end
# File lib/puppet/indirector/indirection.rb, line 215 def find_in_cache(request) # See if our instance is in the cache and up to date. return nil unless cache? and ! request.ignore_cache? and cached = cache.find(request) if cached.expired? Puppet.info "Not using expired #{self.name} for #{request.key} from cache; expired at #{cached.expiration}" return nil end Puppet.debug "Using cached #{self.name} for #{request.key}" cached rescue => detail Puppet.log_exception(detail, "Cached #{self.name} for #{request.key} failed: #{detail}") nil end
Search for an instance in the appropriate terminus, and return a boolean indicating whether the instance was found.
# File lib/puppet/indirector/indirection.rb, line 206 def head(key, options={}) request = request(:head, key, nil, options) terminus = prepare(request) # Look in the cache first, then in the terminus. Force the result # to be a boolean. !!(find_in_cache(request) || terminus.head(request)) end
Set up our request object.
# File lib/puppet/indirector/indirection.rb, line 117 def request(*args) Puppet::Indirector::Request.new(self.name, *args) end
# File lib/puppet/indirector/indirection.rb, line 144 def reset_terminus_class @terminus_class = nil end
Save the instance in the appropriate terminus. This method is normally an instance method on the indirected class.
# File lib/puppet/indirector/indirection.rb, line 262 def save(instance, key = nil, options={}) request = request(:save, key, instance, options) terminus = prepare(request) result = terminus.save(request) # If caching is enabled, save our document there cache.save(request) if cache? result end
Search for more than one instance. Should always return an array.
# File lib/puppet/indirector/indirection.rb, line 246 def search(key, options={}) request = request(:search, key, nil, options) terminus = prepare(request) if result = terminus.search(request) raise Puppet::DevError, "Search results from terminus #{terminus.name} are not an array" unless result.is_a?(Array) result.each do |instance| next unless instance.respond_to? :expiration instance.expiration ||= self.expiration end return result end end
Return the singleton terminus for this indirection.
# File lib/puppet/indirector/indirection.rb, line 122 def terminus(terminus_name = nil) # Get the name of the terminus. raise Puppet::DevError, "No terminus specified for #{self.name}; cannot redirect" unless terminus_name ||= terminus_class termini[terminus_name] ||= make_terminus(terminus_name) end
Determine the terminus class.
# File lib/puppet/indirector/indirection.rb, line 133 def terminus_class unless @terminus_class if setting = self.terminus_setting self.terminus_class = Puppet.settings[setting] else raise Puppet::DevError, "No terminus class nor terminus setting was provided for indirection #{self.name}" end end @terminus_class end
Specify the terminus class to use.
# File lib/puppet/indirector/indirection.rb, line 149 def terminus_class=(klass) validate_terminus_class(klass) @terminus_class = klass end
Default to the runinterval for the ttl.
# File lib/puppet/indirector/indirection.rb, line 74 def ttl @ttl ||= Puppet[:runinterval] end
Set the time-to-live for instances created through this indirection.
# File lib/puppet/indirector/indirection.rb, line 68 def ttl=(value) raise ArgumentError, "Indirection TTL must be an integer" unless value.is_a?(Fixnum) @ttl = value end
This is used by #terminus_class= and cache=.
# File lib/puppet/indirector/indirection.rb, line 155 def validate_terminus_class(terminus_class) raise ArgumentError, "Invalid terminus name #{terminus_class.inspect}" unless terminus_class and terminus_class.to_s != "" unless Puppet::Indirector::Terminus.terminus_class(self.name, terminus_class) raise ArgumentError, "Could not find terminus #{terminus_class} for indirection #{self.name}" end end