class Puppet::Indirector::Indirection

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.

Attributes

cache_class[R]
model[RW]
name[RW]
termini[R]
terminus_setting[RW]

This can be used to select the terminus class.

Public Class Methods

instance(name) click to toggle source

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
instances() click to toggle source

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
model(name) click to toggle source

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
new(model, name, options = {}) click to toggle source
# 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

Public Instance Methods

cache() click to toggle source

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
cache?() click to toggle source

Should we use a cache?

# File lib/puppet/indirector/indirection.rb, line 51
def cache?
  cache_class ? true : false
end
cache_class=(class_name) click to toggle source

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
delete() click to toggle source

This is only used for testing.

# File lib/puppet/indirector/indirection.rb, line 63
def delete
  @@indirections.delete(self) if @@indirections.include?(self)
end
destroy(key, options={}) click to toggle source

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
doc() click to toggle source

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
expiration() click to toggle source

Calculate the expiration date for a returned instance.

# File lib/puppet/indirector/indirection.rb, line 79
def expiration
  Time.now + ttl
end
expire(key, options={}) click to toggle source

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
find(key, options={}) click to toggle source

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
find_in_cache(request) click to toggle source
# 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
head(key, options={}) click to toggle source

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
request(*args) click to toggle source

Set up our request object.

# File lib/puppet/indirector/indirection.rb, line 117
def request(*args)
  Puppet::Indirector::Request.new(self.name, *args)
end
reset_terminus_class() click to toggle source
# File lib/puppet/indirector/indirection.rb, line 144
def reset_terminus_class
  @terminus_class = nil
end
save(instance, key = nil, options={}) click to toggle source

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
terminus(terminus_name = nil) click to toggle source

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
terminus_class() click to toggle source

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
terminus_class=(klass) click to toggle source

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
ttl() click to toggle source

Default to the runinterval for the ttl.

# File lib/puppet/indirector/indirection.rb, line 74
def ttl
  @ttl ||= Puppet[:runinterval]
end
ttl=(value) click to toggle source

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
validate_terminus_class(terminus_class) click to toggle source

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