From 7034882fdfbd3846e77c518e43bdea1f9154e250 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 20 Aug 2008 23:37:13 -0500 Subject: Adding parameter and URL support to the REST terminus. Previously, the server side correctly pulled parameters out of the query strings, but the REST terminus never passed them on. It does now, at least for finding and searching. It appears that at least WEBrick doesn't support parameters for anything other than forms and GET. I've also added the ability for the REST terminus to pull host/port information from the request key, if it's a URI. Signed-off-by: Luke Kanies --- lib/puppet/indirector/rest.rb | 39 ++++++++++++++++++++++++++++++-------- lib/puppet/network/http/handler.rb | 6 +++++- 2 files changed, 36 insertions(+), 9 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index a2767d05b..4389dfb7e 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -32,31 +32,54 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus {"Accept" => model.supported_formats.join(", ")} end - def network - Puppet::Network::HttpPool.http_instance(Puppet[:server], Puppet[:masterport].to_i) + def network(request) + if request.key =~ /^\w+:\/\// # it looks like a URI + begin + uri = URI.parse(URI.escape(request.key)) + rescue => detail + raise ArgumentError, "Could not understand URL %s: %s" % [source, detail.to_s] + end + server = uri.host || Puppet[:server] + port = uri.port.to_i == 0 ? Puppet[:masterport].to_i : uri.port.to_i + else + server = Puppet[:server] + port = Puppet[:masterport].to_i + end + + Puppet::Network::HttpPool.http_instance(server, port) end def find(request) - deserialize network.get("/#{indirection.name}/#{request.key}", headers) + deserialize network(request).get("/#{indirection.name}/#{request.key}#{query_string(request)}", headers) end def search(request) if request.key - path = "/#{indirection.name}s/#{request.key}" + path = "/#{indirection.name}s/#{request.key}#{query_string(request)}" else - path = "/#{indirection.name}s" + path = "/#{indirection.name}s#{query_string(request)}" end - unless result = deserialize(network.get(path, headers), true) + unless result = deserialize(network(request).get(path, headers), true) return [] end return result end def destroy(request) - deserialize network.delete("/#{indirection.name}/#{request.key}", headers) + raise ArgumentError, "DELETE does not accept options" unless request.options.empty? + deserialize network(request).delete("/#{indirection.name}/#{request.key}", headers) end def save(request) - deserialize network.put("/#{indirection.name}/", request.instance.render, headers) + raise ArgumentError, "PUT does not accept options" unless request.options.empty? + deserialize network(request).put("/#{indirection.name}/", request.instance.render, headers) + end + + private + + # Create the qurey string, if options are present. + def query_string(request) + return "" unless request.options and ! request.options.empty? + "?" + request.options.collect { |key, value| "%s=%s" % [key, value] }.join("&") end end diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 291481acd..6f5117b16 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -81,7 +81,11 @@ module Puppet::Network::HTTP::Handler # Execute our search. def do_search(request, response) args = params(request) - result = model.search(args) + if key = request_key(request) + result = model.search(key, args) + else + result = model.search(args) + end if result.nil? or (result.is_a?(Array) and result.empty?) return do_exception(response, "Could not find instances in %s with '%s'" % [model.name, args.inspect], 404) end -- cgit