summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet/indirector/indirection.rb96
1 files changed, 77 insertions, 19 deletions
diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb
index d47433c60..91cc42b17 100644
--- a/lib/puppet/indirector/indirection.rb
+++ b/lib/puppet/indirector/indirection.rb
@@ -1,4 +1,5 @@
require 'puppet/util/docs'
+require 'puppet/indirector/envelope'
# The class that connects functional classes with their different collection
# back-ends. Each indirection has a set of associated terminus classes,
@@ -28,8 +29,7 @@ class Puppet::Indirector::Indirection
# Find an indirected model by name. This is provided so that Terminus classes
# can specifically hook up with the indirections they are associated with.
def self.model(name)
- match = @@indirections.find { |i| i.name == name }
- return nil unless match
+ return nil unless match = @@indirections.find { |i| i.name == name }
match.model
end
@@ -65,6 +65,25 @@ class Puppet::Indirector::Indirection
@@indirections.delete(self) if @@indirections.include?(self)
end
+ # Set the time-to-live for instances created through this indirection.
+ def ttl=(value)
+ raise ArgumentError, "Indirection TTL must be an integer" unless value.is_a?(Fixnum)
+ @ttl = value
+ end
+
+ # Default to the runinterval for the ttl.
+ def ttl
+ unless defined?(@ttl)
+ @ttl = Puppet[:runinterval].to_i
+ end
+ @ttl
+ end
+
+ # Calculate the expiration date for a returned instance.
+ def expiration
+ Time.now + ttl
+ end
+
# Generate the full doc string.
def doc
text = ""
@@ -106,6 +125,12 @@ class Puppet::Indirector::Indirection
end
end
+ # Set the options that can be passed on to the terminus instances.
+ attr_reader :option_struct
+ def options=(options)
+ @option_struct = Struct.new(*options)
+ end
+
# Return the singleton terminus for this indirection.
def terminus(terminus_name = nil)
# Get the name of the terminus.
@@ -161,29 +186,41 @@ class Puppet::Indirector::Indirection
check_authorization(:find, terminus_name, ([key] + args))
# See if our instance is in the cache and up to date.
- if cache? and cache.has_most_recent?(key, terminus(terminus_name).version(key))
- Puppet.debug "Using cached %s %s" % [self.name, key]
- return cache.find(key, *args)
+ if cache? and cached = cache.find(key, *args)
+ if cached.expired?
+ Puppet.info "Cached %s %s expired at %s; not using" % [self.name, key, cached.expiration]
+ else
+ Puppet.debug "Using cached %s %s" % [self.name, key]
+ return cached
+ end
end
# Otherwise, return the result from the terminus, caching if appropriate.
if result = terminus(terminus_name).find(key, *args)
- result.version ||= Time.now.utc
+ # Include the envelope module, so we can set the expiration.
+ result.extend(Puppet::Indirector::Envelope)
+ result.expiration ||= self.expiration
if cache?
Puppet.info "Caching %s %s" % [self.name, key]
cache.save(result, *args)
end
- terminus(terminus_name).post_find(result) if terminus(terminus_name).respond_to?(:post_find)
-
return result
end
+
+ return nil
end
- def destroy(*args)
- check_authorization(:destroy, terminus_class, args)
+ def destroy(key, *args)
+ check_authorization(:destroy, terminus_class, ([key] + args))
+
+ terminus.destroy(key, *args)
+
+ if cache? and cached = cache.find(key, *args)
+ cache.destroy(key, *args)
+ end
- terminus.destroy(*args)
+ nil
end
def search(*args)
@@ -191,21 +228,22 @@ class Puppet::Indirector::Indirection
result = terminus.search(*args)
- terminus().post_search(result) if terminus().respond_to?(:post_search)
-
result
end
# these become instance methods
def save(instance, *args)
- check_authorization(:save, terminus_class, ([instance] + args))
+ if respond_to?(:select_terminus)
+ terminus_name = select_terminus(instance.name, *args)
+ else
+ terminus_name = terminus_class
+ end
- instance.version ||= Time.now.utc
- dest = cache? ? cache : terminus
- return if dest.has_most_recent?(instance.name, instance.version)
- Puppet.info "Caching %s %s" % [self.name, instance.name] if cache?
+ check_authorization(:save, terminus_name, ([instance] + args))
+
+ # If caching is enabled, save our document there, do
cache.save(instance, *args) if cache?
- terminus.save(instance, *args)
+ terminus(terminus_class).save(instance, *args)
end
def version(*args)
@@ -226,6 +264,20 @@ class Puppet::Indirector::Indirection
end
end
+ # Handle a given indirected call.
+ def prepare_call(method, arguments)
+ raise ArgumentError, "Options must be a hash" unless arguments.is_a?(Hash)
+
+ # Set any terminus options.
+ options = option_struct ? set_options(option_struct, arguments) : nil
+
+ tclass = choose_terminus(options)
+
+ check_authorization(method, tclass, options)
+
+ return terminus(tclass), options
+ end
+
# Create a new terminus instance.
def make_terminus(terminus_class)
# Load our terminus class.
@@ -234,4 +286,10 @@ class Puppet::Indirector::Indirection
end
return klass.new
end
+
+ # Create a struct instance with all of the appropriate options set
+ # from the provided hash.
+ def set_options(struct, arguments)
+ struct.new(struct.members.inject([]) { |array, param| arguments[param.to_sym]; array } )
+ end
end