summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-04-08 02:17:31 -0500
committerLuke Kanies <luke@madstop.com>2008-04-08 11:33:50 -0500
commitf9881edd5d4b9f86c1da1c66fb12324d0f9c3c41 (patch)
treedd3d8fd6d93073559162d4c480d7cde95bdf1dfa /lib
parent4032a270d90ef93b39ed1df17ebe1040a11128b9 (diff)
downloadpuppet-f9881edd5d4b9f86c1da1c66fb12324d0f9c3c41.tar.gz
puppet-f9881edd5d4b9f86c1da1c66fb12324d0f9c3c41.tar.xz
puppet-f9881edd5d4b9f86c1da1c66fb12324d0f9c3c41.zip
Adding a Request class to the Indirection layer. This
class is currently only used internally by the Indirection instances, but I expect that I will soon be pushing it to all of the terminus types. I still need to fix a couple of tests that will get broken by this commit.
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet/indirector/indirection.rb89
-rw-r--r--lib/puppet/indirector/request.rb18
2 files changed, 52 insertions, 55 deletions
diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb
index 6f1497319..735fc54da 100644
--- a/lib/puppet/indirector/indirection.rb
+++ b/lib/puppet/indirector/indirection.rb
@@ -1,5 +1,6 @@
require 'puppet/util/docs'
require 'puppet/indirector/envelope'
+require 'puppet/indirector/request'
# The class that connects functional classes with their different collection
# back-ends. Each indirection has a set of associated terminus classes,
@@ -125,12 +126,6 @@ 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.
@@ -173,17 +168,8 @@ class Puppet::Indirector::Indirection
end
def find(key, *args)
- # Select the appropriate terminus if there's a hook
- # for doing so. This allows the caller to pass in some kind
- # of URI that the indirection can use for routing to the appropriate
- # terminus.
- if respond_to?(:select_terminus)
- terminus_name = select_terminus(key, *args)
- else
- terminus_name = terminus_class
- end
-
- check_authorization(:find, terminus_name, ([key] + args))
+ request = request(key, :find, *args)
+ terminus = prepare(request)
# See if our instance is in the cache and up to date.
if cache? and cached = cache.find(key, *args)
@@ -196,7 +182,7 @@ class Puppet::Indirector::Indirection
end
# Otherwise, return the result from the terminus, caching if appropriate.
- if result = terminus(terminus_name).find(key, *args)
+ if result = terminus.find(key, *args)
# Include the envelope module, so we can set the expiration.
result.extend(Puppet::Indirector::Envelope)
result.expiration ||= self.expiration
@@ -213,7 +199,8 @@ class Puppet::Indirector::Indirection
# Remove something via the terminus.
def destroy(key, *args)
- check_authorization(:destroy, terminus_class, ([key] + args))
+ request = request(key, :destroy, *args)
+ terminus = prepare(request)
terminus.destroy(key, *args)
@@ -225,59 +212,52 @@ class Puppet::Indirector::Indirection
end
# Search for more than one instance. Should always return an array.
- def search(*args)
- check_authorization(:search, terminus_class, args)
+ def search(key, *args)
+ request = request(key, :search, *args)
+ terminus = prepare(request)
- result = terminus.search(*args)
+ result = terminus.search(key, *args)
result
end
- # these become instance methods
+ # Save the instance in the appropriate terminus. This method is
+ # normally an instance method on the indirected class.
def save(instance, *args)
- if respond_to?(:select_terminus)
- terminus_name = select_terminus(instance.name, *args)
- else
- terminus_name = terminus_class
- end
-
- check_authorization(:save, terminus_name, ([instance] + args))
+ request = request(instance.name, :save, *args)
+ terminus = prepare(request)
# If caching is enabled, save our document there, do
cache.save(instance, *args) if cache?
- terminus(terminus_class).save(instance, *args)
- end
-
- def version(*args)
- terminus.version(*args)
+ terminus.save(instance, *args)
end
private
# Check authorization if there's a hook available; fail if there is one
# and it returns false.
- def check_authorization(method, terminus_name, arguments)
- # Don't check authorization if there's no node.
- # LAK:FIXME This is a hack and is quite possibly not the design we want.
- return unless arguments[-1].is_a?(Hash) and arguments[-1][:node]
+ def check_authorization(request, terminus)
+ return unless request.options[:node]
- if terminus(terminus_name).respond_to?(:authorized?) and ! terminus(terminus_name).authorized?(method, *arguments)
- raise ArgumentError, "Not authorized to call %s with %s" % [method, arguments[0]]
+ return unless terminus.respond_to?(:authorized?)
+
+ unless terminus.authorized?(request)
+ raise ArgumentError, "Not authorized to call %s with %s" % [request.method, request.options.inspect]
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)
+ # Setup a request, pick the appropriate terminus, check the request's authorization, and return it.
+ def prepare(request)
+ # Pick our terminus.
+ if respond_to?(:select_terminus)
+ terminus_name = select_terminus(request)
+ else
+ terminus_name = terminus_class
+ end
- check_authorization(method, tclass, options)
+ check_authorization(request, terminus(terminus_name))
- return terminus(tclass), options
+ return terminus(terminus_name)
end
# Create a new terminus instance.
@@ -289,9 +269,8 @@ class Puppet::Indirector::Indirection
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 } )
+ # Set up our request object.
+ def request(key, method, arguments = nil)
+ Puppet::Indirector::Request.new(self.name, key, method, arguments)
end
end
diff --git a/lib/puppet/indirector/request.rb b/lib/puppet/indirector/request.rb
new file mode 100644
index 000000000..a5495641d
--- /dev/null
+++ b/lib/puppet/indirector/request.rb
@@ -0,0 +1,18 @@
+require 'puppet/indirector'
+
+# Provide any attributes or functionality needed for indirected
+# instances.
+class Puppet::Indirector::Request
+ attr_accessor :indirection_name, :key, :method, :options
+
+ def initialize(indirection_name, key, method, options = {})
+ @indirection_name, @key, @method, @options = indirection_name, key, method, (options || {})
+
+ raise ArgumentError, "Request options must be a hash, not %s" % @options.class unless @options.is_a?(Hash)
+ end
+
+ # Look up the indirection based on the name provided.
+ def indirection
+ Puppet::Indirector::Indirection.instance(@indirection_name)
+ end
+end