From 2cdd0f89a8d6687fafa77bf119cf2bbeed9d5b71 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 19 Feb 2008 12:49:57 -0600 Subject: puppet-compliant indentation --- lib/puppet/network/server.rb | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/network/server.rb b/lib/puppet/network/server.rb index 50e3bd686..9e6b82469 100644 --- a/lib/puppet/network/server.rb +++ b/lib/puppet/network/server.rb @@ -8,44 +8,44 @@ class Puppet::Network::Server raise(ArgumentError, "Must specify :address or configure Puppet :bindaddress.") @port = args[:port] || Puppet[:masterport] || raise(ArgumentError, "Must specify :port or configure Puppet :masterport") - @protocols = [] - @listening = false - @routes = {} - self.register(args[:handlers]) if args[:handlers] + @protocols = [] + @listening = false + @routes = {} + self.register(args[:handlers]) if args[:handlers] end def register(*indirections) - raise ArgumentError, "Indirection names are required." if indirections.empty? - indirections.flatten.each { |i| @routes[i.to_sym] = true } + raise ArgumentError, "Indirection names are required." if indirections.empty? + indirections.flatten.each { |i| @routes[i.to_sym] = true } end def unregister(*indirections) - raise "Cannot unregister indirections while server is listening." if listening? - indirections = @routes.keys if indirections.empty? - - indirections.flatten.each do |i| - raise(ArgumentError, "Indirection [%s] is unknown." % i) unless @routes[i.to_sym] - end + raise "Cannot unregister indirections while server is listening." if listening? + indirections = @routes.keys if indirections.empty? + + indirections.flatten.each do |i| + raise(ArgumentError, "Indirection [%s] is unknown." % i) unless @routes[i.to_sym] + end - indirections.flatten.each do |i| - @routes.delete(i.to_sym) - end + indirections.flatten.each do |i| + @routes.delete(i.to_sym) + end end def listening? - @listening + @listening end def listen - raise "Cannot listen -- already listening." if listening? - http_server.listen(@routes.dup) - @listening = true + raise "Cannot listen -- already listening." if listening? + http_server.listen(@routes.dup) + @listening = true end def unlisten - raise "Cannot unlisten -- not currently listening." unless listening? - http_server.unlisten - @listening = false + raise "Cannot unlisten -- not currently listening." unless listening? + http_server.unlisten + @listening = false end def http_server_class -- cgit From 13c40e93a5f65255dd3cf93955e83121cc5bb594 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 19 Feb 2008 13:34:55 -0600 Subject: removing obsolete TODO comment --- lib/puppet/network/http/mongrel.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/puppet') diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index 8ea669531..4593f6569 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -45,7 +45,6 @@ class Puppet::Network::HTTP::Mongrel end end - # TODO/FIXME: need a spec which forces delegation to the real class def class_for_protocol(protocol) return Puppet::Network::HTTP::MongrelREST if protocol.to_sym == :rest return Puppet::Network::HTTP::MongrelXMLRPC if protocol.to_sym == :xmlrpc -- cgit From c2f8c69af368a8ba496da4ef0023ac5f0885e3c0 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 19 Feb 2008 15:06:00 -0600 Subject: the indirector will not serve xmlrpc (this is the responsibility of the legacy networking code; it was a mistake to include stubbed support for it in the new code); removing --- lib/puppet/network/http/mongrel.rb | 2 -- lib/puppet/network/http/mongrel/xmlrpc.rb | 4 ---- lib/puppet/network/http/webrick.rb | 2 -- lib/puppet/network/http/webrick/xmlrpc.rb | 4 ---- 4 files changed, 12 deletions(-) delete mode 100644 lib/puppet/network/http/mongrel/xmlrpc.rb delete mode 100644 lib/puppet/network/http/webrick/xmlrpc.rb (limited to 'lib/puppet') diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index 4593f6569..d948836cd 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -1,7 +1,6 @@ require 'mongrel' if Puppet.features.mongrel? require 'puppet/network/http/mongrel/rest' -require 'puppet/network/http/mongrel/xmlrpc' class Puppet::Network::HTTP::Mongrel def initialize(args = {}) @@ -47,7 +46,6 @@ class Puppet::Network::HTTP::Mongrel def class_for_protocol(protocol) return Puppet::Network::HTTP::MongrelREST if protocol.to_sym == :rest - return Puppet::Network::HTTP::MongrelXMLRPC if protocol.to_sym == :xmlrpc raise ArgumentError, "Unknown protocol [#{protocol}]." end end diff --git a/lib/puppet/network/http/mongrel/xmlrpc.rb b/lib/puppet/network/http/mongrel/xmlrpc.rb deleted file mode 100644 index 92acd4f0e..000000000 --- a/lib/puppet/network/http/mongrel/xmlrpc.rb +++ /dev/null @@ -1,4 +0,0 @@ -class Puppet::Network::HTTP::MongrelXMLRPC - def initialize(args = {}) - end -end diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index c4b2ed3c6..894e12473 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -1,7 +1,6 @@ require 'webrick' require 'webrick/https' require 'puppet/network/http/webrick/rest' -require 'puppet/network/http/webrick/xmlrpc' class Puppet::Network::HTTP::WEBrick def initialize(args = {}) @@ -45,7 +44,6 @@ class Puppet::Network::HTTP::WEBrick def class_for_protocol(protocol) return Puppet::Network::HTTP::WEBrickREST if protocol.to_sym == :rest - return Puppet::Network::HTTP::WEBrickXMLRPC if protocol.to_sym == :xmlrpc raise ArgumentError, "Unknown protocol [#{protocol}]." end end diff --git a/lib/puppet/network/http/webrick/xmlrpc.rb b/lib/puppet/network/http/webrick/xmlrpc.rb deleted file mode 100644 index 793708f8a..000000000 --- a/lib/puppet/network/http/webrick/xmlrpc.rb +++ /dev/null @@ -1,4 +0,0 @@ -class Puppet::Network::HTTP::WEBrickXMLRPC - def initialize(args = {}) - end -end -- cgit From e86fde2facafd56ee12d7e748b1c8cad916253bf Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Wed, 12 Mar 2008 22:26:12 -0500 Subject: This is the first version where mongrel and webrick are reliably startable and stoppable via Puppet::Network::Server. Added a network/server integration spec, testing startup, shutdown, reachability, and collision of webrick and mongrel servers in the new network code. Converted Puppet::Network::HTTP::Handler class to a module, as mongrel Handler should be subclassed; converting subclasses to include the module instead. Mongrel will actually stop if you .stop it, graceful_shutdown didn't seem quite so reliable. Webrick requires running in its own Thread to avoid hanging the entire process; this requires introduction of a Mutex to make things safe. We're only supporting the REST protocol. Made this explicit. Fixed http server setup args, w/ specs, ah the glory of integration testing. --- lib/puppet/network/http/handler.rb | 5 +++-- lib/puppet/network/http/mongrel.rb | 10 +++++----- lib/puppet/network/http/mongrel/rest.rb | 13 +++++++++++-- lib/puppet/network/http/webrick.rb | 25 ++++++++++++++++++------- lib/puppet/network/http/webrick/rest.rb | 4 +++- lib/puppet/network/server.rb | 6 ++++-- 6 files changed, 44 insertions(+), 19 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 773381c8d..7679bf320 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -1,4 +1,5 @@ -class Puppet::Network::HTTP::Handler +module Puppet::Network::HTTP::Handler + def initialize(args = {}) raise ArgumentError unless @server = args[:server] raise ArgumentError unless @handler = args[:handler] @@ -77,7 +78,7 @@ class Puppet::Network::HTTP::Handler %r{/#{@handler.to_s}s$}.match(path(request)) end - # methods specific to a given web server + # methods to be overridden by the including web server class def register_handler raise NotImplementedError diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index d948836cd..941ef0e43 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -13,20 +13,20 @@ class Puppet::Network::HTTP::Mongrel raise ArgumentError, ":address must be specified." unless args[:address] raise ArgumentError, ":port must be specified." unless args[:port] raise "Mongrel server is already listening" if listening? - + @protocols = args[:protocols] @handlers = args[:handlers] - @server = Mongrel::HttpServer.new(args[:address], args[:port]) - + @server = Mongrel::HttpServer.new(args[:address], args[:port]) setup_handlers - @server.run @listening = true + @server.run end def unlisten raise "Mongrel server is not listening" unless listening? - @server.graceful_shutdown + @server.stop + @server = nil @listening = false end diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index 6c24e360c..7cb6f67bf 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -1,36 +1,45 @@ require 'puppet/network/http/handler' -class Puppet::Network::HTTP::MongrelREST < Puppet::Network::HTTP::Handler +class Puppet::Network::HTTP::MongrelREST < Mongrel::HttpHandler + + include Puppet::Network::HTTP::Handler private - + + # have this mongrel @server listen for /foo and /foos REST endpoints def register_handler @server.register('/' + @handler.to_s, self) @server.register('/' + @handler.to_s + 's', self) end + # which HTTP verb was used in this request def http_method(request) request.params[Mongrel::Const::REQUEST_METHOD] end + # what path was requested? def path(request) # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com] x = '/' + request.params[Mongrel::Const::REQUEST_PATH].split('/')[1] end + # return the key included in the request path def request_key(request) # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com] x = request.params[Mongrel::Const::REQUEST_PATH].split('/')[2] end + # return the request body def body(request) request.body end + # return the query params for this request def params(request) Mongrel::HttpRequest.query_parse(request.params["QUERY_STRING"]) end + # produce the body of the response def encode_result(request, response, result, status = 200) response.start(status) do |head, body| body.write(result) diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index 894e12473..3fd643612 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -1,10 +1,12 @@ require 'webrick' require 'webrick/https' require 'puppet/network/http/webrick/rest' +require 'thread' class Puppet::Network::HTTP::WEBrick def initialize(args = {}) @listening = false + @mutex = Mutex.new end def listen(args = {}) @@ -12,24 +14,33 @@ class Puppet::Network::HTTP::WEBrick raise ArgumentError, ":protocols must be specified." if !args[:protocols] or args[:protocols].empty? raise ArgumentError, ":address must be specified." unless args[:address] raise ArgumentError, ":port must be specified." unless args[:port] - raise "WEBrick server is already listening" if listening? @protocols = args[:protocols] @handlers = args[:handlers] @server = WEBrick::HTTPServer.new(:BindAddress => args[:address], :Port => args[:port]) setup_handlers - @server.start - @listening = true + + @mutex.synchronize do + raise "WEBrick server is already listening" if @listening + @listening = true + @thread = Thread.new { @server.start } + end end def unlisten - raise "WEBrick server is not listening" unless listening? - @server.shutdown - @listening = false + @mutex.synchronize do + raise "WEBrick server is not listening" unless @listening + @server.shutdown + @thread.join + @server = nil + @listening = false + end end def listening? - @listening + @mutex.synchronize do + @listening + end end private diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index 8cda079e2..923e002e3 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -1,6 +1,8 @@ require 'puppet/network/http/handler' -class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler +class Puppet::Network::HTTP::WEBrickREST + + include Puppet::Network::HTTP::Handler # WEBrick uses a service() method to respond to requests. Simply delegate to the handler response() method. def service(request, response) diff --git a/lib/puppet/network/server.rb b/lib/puppet/network/server.rb index 9e6b82469..cab14519b 100644 --- a/lib/puppet/network/server.rb +++ b/lib/puppet/network/server.rb @@ -1,3 +1,5 @@ +require 'puppet/network/http' + class Puppet::Network::Server attr_reader :server_type, :protocols, :address, :port @@ -8,7 +10,7 @@ class Puppet::Network::Server raise(ArgumentError, "Must specify :address or configure Puppet :bindaddress.") @port = args[:port] || Puppet[:masterport] || raise(ArgumentError, "Must specify :port or configure Puppet :masterport") - @protocols = [] + @protocols = [ :rest ] @listening = false @routes = {} self.register(args[:handlers]) if args[:handlers] @@ -38,8 +40,8 @@ class Puppet::Network::Server def listen raise "Cannot listen -- already listening." if listening? - http_server.listen(@routes.dup) @listening = true + http_server.listen(:address => address, :port => port, :handlers => @routes.keys, :protocols => protocols) end def unlisten -- cgit From 7d51146e98e4135d933be5b2b227a0ca92f06ef2 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Wed, 12 Mar 2008 23:08:13 -0500 Subject: fixing Puppet::Node::REST class name to work with autoloader inflection (Puppet::Node::Rest), so we can do Puppet::Node.terminus_class = :rest --- lib/puppet/indirector/node/rest.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/node/rest.rb b/lib/puppet/indirector/node/rest.rb index c5d2f97fb..d8b75f6e7 100644 --- a/lib/puppet/indirector/node/rest.rb +++ b/lib/puppet/indirector/node/rest.rb @@ -1,7 +1,7 @@ require 'puppet/node' require 'puppet/indirector/rest' -class Puppet::Node::REST < Puppet::Indirector::REST +class Puppet::Node::Rest < Puppet::Indirector::REST desc "This will eventually be a REST-based mechanism for finding nodes. It is currently non-functional." # TODO/FIXME end -- cgit From 7a7343458402e493f690633f3cfa78abef316d28 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Mon, 31 Mar 2008 11:59:16 -0500 Subject: Much larger commit than I would like to land at once. This is all REST-related code. Two specs are failing related to how Mongrel is initialized for REST; will fix those shortly. REST indirector now supports find, with deserialization. Network code in indirector now. Will still need to un-hardwire address/port for outbound connections. Will still need to urlencode path parameters. Code for search, destroy, update is coming, should be similar to find. Reworked how the Handler module is used. Needed to be included, rather than inherited. Needed to sidestep initializers for actual web servers (webrick, mongrel), needed to be possible to have handler-including class be used as a class (aka servlet) instead of as an instance. Webrick handler registration is now abstracted to "above" the servlet. Provided a #model method to use instead of @model in handler module. This allows neutering during testing. Brought class_for_protocol up into http/webrick class as a (tested) class method. Integration tests for rest indirection. Split server integration tests into mongrel and webrick tests. Got Node/REST working properly wrt the crazy-ass autoloader thing. We're now actually passing traffic w/ webrick, fwiw. --- lib/puppet/indirector/rest.rb | 12 ++++++++++-- lib/puppet/network/http/handler.rb | 17 ++++++++++------- lib/puppet/network/http/mongrel/rest.rb | 4 ++++ lib/puppet/network/http/webrick.rb | 16 +++++++++------- lib/puppet/network/http/webrick/rest.rb | 17 +++++++++-------- 5 files changed, 42 insertions(+), 24 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index 7b7c932c4..4c54183c6 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -1,8 +1,16 @@ -require 'puppet/indirector/rest' +require 'net/http' +require 'uri' # Access objects via REST class Puppet::Indirector::REST < Puppet::Indirector::Terminus + def network_fetch(path) + # TODO: url_encode path, set proper server + port + Net::HTTP.get(URI.parse("http://127.0.0.1:34343/#{path}")) + end + def find(name, options = {}) - indirection.model.new(name) + network_result = network_fetch("#{indirection.name}/#{name}") + raise YAML.load(network_result) if network_result =~ %r{--- !ruby/exception} + decoded_result = indirection.model.from_yaml(network_result) end end diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 7679bf320..b5dcf69d4 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -1,10 +1,9 @@ module Puppet::Network::HTTP::Handler - - def initialize(args = {}) + + def initialize_for_puppet(args = {}) raise ArgumentError unless @server = args[:server] raise ArgumentError unless @handler = args[:handler] @model = find_model_for_handler(@handler) - register_handler end # handle an HTTP request @@ -19,24 +18,28 @@ module Puppet::Network::HTTP::Handler end private + + def model + @model + end def do_find(request, response) key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]") args = params(request) - result = @model.find(key, args).to_yaml + result = model.find(key, args).to_yaml encode_result(request, response, result) end def do_search(request, response) args = params(request) - result = @model.search(args).collect {|obj| obj.to_yaml } + result = model.search(args).collect {|obj| obj.to_yaml } encode_result(request, response, result) end def do_destroy(request, response) key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]") args = params(request) - result = @model.destroy(key, args) + result = model.destroy(key, args) encode_result(request, response, YAML.dump(result)) end @@ -44,7 +47,7 @@ module Puppet::Network::HTTP::Handler data = body(request) raise ArgumentError, "No data to save" if !data or data.empty? args = params(request) - obj = @model.new + obj = model.new result = obj.save(args.merge(:data => data)).to_yaml encode_result(request, response, result) end diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index 7cb6f67bf..d7a1a1bdc 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -3,6 +3,10 @@ require 'puppet/network/http/handler' class Puppet::Network::HTTP::MongrelREST < Mongrel::HttpHandler include Puppet::Network::HTTP::Handler + + def initialize(args={}) + initialize_for_puppet(args) + end private diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index 3fd643612..3a37e2071 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -9,6 +9,11 @@ class Puppet::Network::HTTP::WEBrick @mutex = Mutex.new end + def self.class_for_protocol(protocol) + return Puppet::Network::HTTP::WEBrickREST if protocol.to_sym == :rest + raise "Unknown protocol [#{protocol}]." + end + def listen(args = {}) raise ArgumentError, ":handlers must be specified." if !args[:handlers] or args[:handlers].empty? raise ArgumentError, ":protocols must be specified." if !args[:protocols] or args[:protocols].empty? @@ -42,19 +47,16 @@ class Puppet::Network::HTTP::WEBrick @listening end end - + private def setup_handlers @protocols.each do |protocol| + klass = self.class.class_for_protocol(protocol) @handlers.each do |handler| - class_for_protocol(protocol).new(:server => @server, :handler => handler) + @server.mount('/' + handler.to_s, klass, handler) + @server.mount('/' + handler.to_s + 's', klass, handler) end end end - - def class_for_protocol(protocol) - return Puppet::Network::HTTP::WEBrickREST if protocol.to_sym == :rest - raise ArgumentError, "Unknown protocol [#{protocol}]." - end end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index 923e002e3..b43912196 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -1,21 +1,22 @@ require 'puppet/network/http/handler' -class Puppet::Network::HTTP::WEBrickREST - +class Puppet::Network::HTTP::WEBrickREST < WEBrick::HTTPServlet::AbstractServlet + include Puppet::Network::HTTP::Handler + + def initialize(server, handler) + raise ArgumentError, "server is required" unless server + super(server) + initialize_for_puppet(:server => server, :handler => handler) + end # WEBrick uses a service() method to respond to requests. Simply delegate to the handler response() method. def service(request, response) process(request, response) end - + private - def register_handler - @server.mount('/' + @handler.to_s, self) - @server.mount('/' + @handler.to_s + 's', self) - end - def http_method(request) request.request_method end -- cgit From d24c03c9bbcc35a94a8235c030a73233feabad57 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Mon, 31 Mar 2008 12:08:36 -0500 Subject: exceptions on remote end now properly passed to local end via REST and re-raised (integration-tested) --- lib/puppet/network/http/handler.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/puppet') diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index b5dcf69d4..f226ae133 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -53,7 +53,7 @@ module Puppet::Network::HTTP::Handler end def do_exception(request, response, exception, status=404) - encode_result(request, response, exception.to_s, status) + encode_result(request, response, exception.to_yaml, status) end def find_model_for_handler(handler) -- cgit From 1e0f19bcbd0c3f5a83f9cad0e90eb5d6478e278b Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 1 Apr 2008 22:55:22 -0500 Subject: Make mongrel happy like WEBrick. Refactored specs to put some of the lower-level find/save/search/destroy unit tests under their own contexts. --- lib/puppet/network/http/mongrel.rb | 4 +++- lib/puppet/network/http/mongrel/rest.rb | 7 +------ 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index 941ef0e43..9a4531c7a 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -38,8 +38,10 @@ class Puppet::Network::HTTP::Mongrel def setup_handlers @protocols.each do |protocol| + klass = class_for_protocol(protocol) @handlers.each do |handler| - class_for_protocol(protocol).new(:server => @server, :handler => handler) + @server.register('/' + handler.to_s, klass.new(:server => @server, :handler => handler)) + @server.register('/' + handler.to_s + 's', klass.new(:server => @server, :handler => handler)) end end end diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index d7a1a1bdc..2a3d4f143 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -5,17 +5,12 @@ class Puppet::Network::HTTP::MongrelREST < Mongrel::HttpHandler include Puppet::Network::HTTP::Handler def initialize(args={}) + super() initialize_for_puppet(args) end private - # have this mongrel @server listen for /foo and /foos REST endpoints - def register_handler - @server.register('/' + @handler.to_s, self) - @server.register('/' + @handler.to_s + 's', self) - end - # which HTTP verb was used in this request def http_method(request) request.params[Mongrel::Const::REQUEST_METHOD] -- cgit From b75048202219f2e07a211df3400a0ee88ccfd208 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 1 Apr 2008 23:40:28 -0500 Subject: unit specs and implementation for Indirector::REST#search method --- lib/puppet/indirector/rest.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index 4c54183c6..690c79632 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -13,4 +13,12 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus raise YAML.load(network_result) if network_result =~ %r{--- !ruby/exception} decoded_result = indirection.model.from_yaml(network_result) end + + def search(key, options = {}) + network_results = network_fetch("#{indirection.name}s/#{key}") + raise YAML.load(network_results) if network_results =~ %r{--- !ruby/exception} + decoded_results = network_results.collect do |result| + indirection.model.from_yaml(result) + end + end end -- cgit From e8caf135a4a378d54bf62f8c37064ee3ccc508e9 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Wed, 2 Apr 2008 00:06:30 -0500 Subject: making search work over REST, w/ unit & integration specs --- lib/puppet/indirector/rest.rb | 4 +--- lib/puppet/network/http/handler.rb | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index 690c79632..0c86b2706 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -17,8 +17,6 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus def search(key, options = {}) network_results = network_fetch("#{indirection.name}s/#{key}") raise YAML.load(network_results) if network_results =~ %r{--- !ruby/exception} - decoded_results = network_results.collect do |result| - indirection.model.from_yaml(result) - end + decoded_results = YAML.load(network_results.to_s).collect {|result| indirection.model.from_yaml(result) } end end diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index f226ae133..9e6c28512 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -32,7 +32,7 @@ module Puppet::Network::HTTP::Handler def do_search(request, response) args = params(request) - result = model.search(args).collect {|obj| obj.to_yaml } + result = model.search(args).collect {|result| result.to_yaml }.to_yaml encode_result(request, response, result) end -- cgit From f28f20b675737741a98b1b87b4791f736a996d40 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Wed, 2 Apr 2008 00:48:54 -0500 Subject: Added support for destroy/DELETE over REST (including units & integrations on both webrick & mongrel). Added pending specs for the trivialities in the REST network_fetch and network_delete methods. Refactored YAML exception detection out into a private helper method. --- lib/puppet/indirector/rest.rb | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index 0c86b2706..076e96356 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -4,19 +4,38 @@ require 'uri' # Access objects via REST class Puppet::Indirector::REST < Puppet::Indirector::Terminus def network_fetch(path) - # TODO: url_encode path, set proper server + port Net::HTTP.get(URI.parse("http://127.0.0.1:34343/#{path}")) end + def network_delete(path) + Net::HTTP.start("127.0.0.1", 34343) {|x| x.delete("/#{path}").body } # weird-ass net/http library + end + def find(name, options = {}) - network_result = network_fetch("#{indirection.name}/#{name}") - raise YAML.load(network_result) if network_result =~ %r{--- !ruby/exception} - decoded_result = indirection.model.from_yaml(network_result) + network_result = network_fetch("#{indirection.name}/#{name}") + raise YAML.load(network_result) if exception?(network_result) + decoded_result = indirection.model.from_yaml(network_result) + end + + def search(name, options = {}) + network_results = network_fetch("#{indirection.name}s/#{name}") + raise YAML.load(network_results) if exception?(network_results) + decoded_results = YAML.load(network_results.to_s).collect {|result| indirection.model.from_yaml(result) } + end + + def destroy(name, options = {}) + network_result = network_delete("#{indirection.name}/#{name}") + raise YAML.load(network_result) if exception?(network_result) + decoded_result = YAML.load(network_result.to_s) + end + + def save + end - def search(key, options = {}) - network_results = network_fetch("#{indirection.name}s/#{key}") - raise YAML.load(network_results) if network_results =~ %r{--- !ruby/exception} - decoded_results = YAML.load(network_results.to_s).collect {|result| indirection.model.from_yaml(result) } + private + + def exception?(yaml_string) + yaml_string =~ %r{--- !ruby/exception} end end -- cgit From 1befd1d8f1d389f425a36b1515dbba7408ac6238 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Wed, 2 Apr 2008 01:15:53 -0500 Subject: work-in-progress; playing with refactoring network_* methods inside Indirector::REST --- lib/puppet/indirector/rest.rb | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index 076e96356..33ae34006 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -4,11 +4,20 @@ require 'uri' # Access objects via REST class Puppet::Indirector::REST < Puppet::Indirector::Terminus def network_fetch(path) - Net::HTTP.get(URI.parse("http://127.0.0.1:34343/#{path}")) + network(path, 'get') end def network_delete(path) - Net::HTTP.start("127.0.0.1", 34343) {|x| x.delete("/#{path}").body } # weird-ass net/http library + network(path, 'delete') + end + + def network_put(path, data) + network(path, 'put', data) + end + + def network(path, meth, data = nil) + # TODO: include data here, for #save + Net::HTTP.start("127.0.0.1", 34343) {|x| x.send(meth.to_sym, "/#{path}").body } # weird-ass net/http library end def find(name, options = {}) -- cgit From 99b295b8301d7a89c97ecdc1d636c2d2b7f1ae8e Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Wed, 2 Apr 2008 19:28:11 -0500 Subject: disabling caching for Puppet::Indirector::Indirection as it was causing hella problems with testing save without caching; judging my luke's blog this is going to be rewritten somehow anyway --- lib/puppet/indirector/indirection.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb index 15358a801..606234dd0 100644 --- a/lib/puppet/indirector/indirection.rb +++ b/lib/puppet/indirector/indirection.rb @@ -242,7 +242,6 @@ class Puppet::Indirector::Indirection if result = terminus.search(request) raise Puppet::DevError, "Search results from terminus %s are not an array" % terminus.name unless result.is_a?(Array) - result.each do |instance| instance.expiration ||= self.expiration end -- cgit From 93bc1a946f2da6e7c78a38ff90dac8a20b1bcbc7 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Wed, 2 Apr 2008 19:29:04 -0500 Subject: adding REST save support, with integration tests. A handful of unit tests in that area now need to be updated. --- lib/puppet/indirector/rest.rb | 27 +++++++++++++-------------- lib/puppet/network/http/handler.rb | 12 ++++++++---- 2 files changed, 21 insertions(+), 18 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index 33ae34006..889f63648 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -4,47 +4,46 @@ require 'uri' # Access objects via REST class Puppet::Indirector::REST < Puppet::Indirector::Terminus def network_fetch(path) - network(path, 'get') + Net::HTTP.start("127.0.0.1", 34343) {|x| x.get("/#{path}").body } end def network_delete(path) - network(path, 'delete') + Net::HTTP.start("127.0.0.1", 34343) {|x| x.delete("/#{path}").body } end def network_put(path, data) - network(path, 'put', data) - end - - def network(path, meth, data = nil) - # TODO: include data here, for #save - Net::HTTP.start("127.0.0.1", 34343) {|x| x.send(meth.to_sym, "/#{path}").body } # weird-ass net/http library + Net::HTTP.start("127.0.0.1", 34343) {|x| x.put("/#{path}", data).body } end def find(name, options = {}) network_result = network_fetch("#{indirection.name}/#{name}") raise YAML.load(network_result) if exception?(network_result) - decoded_result = indirection.model.from_yaml(network_result) + indirection.model.from_yaml(network_result) end def search(name, options = {}) network_results = network_fetch("#{indirection.name}s/#{name}") raise YAML.load(network_results) if exception?(network_results) - decoded_results = YAML.load(network_results.to_s).collect {|result| indirection.model.from_yaml(result) } + YAML.load(network_results.to_s).collect {|result| indirection.model.from_yaml(result) } end def destroy(name, options = {}) network_result = network_delete("#{indirection.name}/#{name}") raise YAML.load(network_result) if exception?(network_result) - decoded_result = YAML.load(network_result.to_s) + YAML.load(network_result.to_s) end - def save - + def save(obj, options = {}) + network_result = network_put("#{indirection.name}/", obj.to_yaml) + # TODO: swap these two lines out: + raise network_result.inspect if exception?(network_result) + # raise YAML.load(network_result) if exception?(network_result) + indirection.model.from_yaml(network_result) end private def exception?(yaml_string) - yaml_string =~ %r{--- !ruby/exception} + yaml_string =~ %r{--- !ruby/exception} end end diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 9e6c28512..7113c92d3 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -44,13 +44,17 @@ module Puppet::Network::HTTP::Handler end def do_save(request, response) - data = body(request) + data = body(request).to_s raise ArgumentError, "No data to save" if !data or data.empty? - args = params(request) - obj = model.new - result = obj.save(args.merge(:data => data)).to_yaml + # args = params(request) + obj = model.from_yaml(data) + result = save_object(obj).to_yaml encode_result(request, response, result) end + + def save_object(obj) + obj.save + end def do_exception(request, response, exception, status=404) encode_result(request, response, exception.to_yaml, status) -- cgit From 75bf05d516ebdace19703c1c1bca5d2cc65d1001 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Wed, 2 Apr 2008 20:30:20 -0500 Subject: removed a debugging helper from the Indirector::Rest#save method --- lib/puppet/indirector/rest.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index 889f63648..546cbdaf7 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -35,9 +35,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus def save(obj, options = {}) network_result = network_put("#{indirection.name}/", obj.to_yaml) - # TODO: swap these two lines out: - raise network_result.inspect if exception?(network_result) - # raise YAML.load(network_result) if exception?(network_result) + raise YAML.load(network_result) if exception?(network_result) indirection.model.from_yaml(network_result) end -- cgit From a0804ae29a4d2be7b3f15015f87f5b274e95c7bd Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Wed, 2 Apr 2008 20:45:51 -0500 Subject: adding rest_connection_details helper to Indirector::REST -- will need to be overridden to lookup the real connection details --- lib/puppet/indirector/rest.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index 546cbdaf7..e6a7bd6cf 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -3,6 +3,11 @@ require 'uri' # Access objects via REST class Puppet::Indirector::REST < Puppet::Indirector::Terminus + + def rest_connection_details + { :host => '127.0.0.1', :port => 34343 } + end + def network_fetch(path) Net::HTTP.start("127.0.0.1", 34343) {|x| x.get("/#{path}").body } end -- cgit From 04aba5253d774fae013919605363022781f16d55 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Wed, 2 Apr 2008 21:27:14 -0500 Subject: fill out specs for network_* methods; refactor lowest-level network hooks --- lib/puppet/indirector/rest.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index e6a7bd6cf..34596cad4 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -5,19 +5,19 @@ require 'uri' class Puppet::Indirector::REST < Puppet::Indirector::Terminus def rest_connection_details - { :host => '127.0.0.1', :port => 34343 } + { :host => '127.0.0.1', :port => 34343 } end def network_fetch(path) - Net::HTTP.start("127.0.0.1", 34343) {|x| x.get("/#{path}").body } + network {|conn| conn.get("/#{path}").body } end def network_delete(path) - Net::HTTP.start("127.0.0.1", 34343) {|x| x.delete("/#{path}").body } + network {|conn| conn.delete("/#{path}").body } end def network_put(path, data) - Net::HTTP.start("127.0.0.1", 34343) {|x| x.put("/#{path}", data).body } + network {|conn| conn.put("/#{path}", data).body } end def find(name, options = {}) @@ -46,6 +46,10 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus private + def network(&block) + Net::HTTP.start(rest_connection_details[:host], rest_connection_details[:port]) {|conn| yield(conn) } + end + def exception?(yaml_string) yaml_string =~ %r{--- !ruby/exception} end -- cgit From a6a397b21ce9306307c7614b671de63d74d8141e Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Fri, 11 Apr 2008 13:50:36 -0500 Subject: The 'destroy' method in the indirection now returns the results of destroying, so they can return true or false. --- lib/puppet/indirector/indirection.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb index 606234dd0..05464f8c9 100644 --- a/lib/puppet/indirector/indirection.rb +++ b/lib/puppet/indirector/indirection.rb @@ -225,14 +225,14 @@ class Puppet::Indirector::Indirection request = request(:destroy, key, *args) terminus = prepare(request) - terminus.destroy(request) + result = terminus.destroy(request) if cache? and cached = cache.find(request(:find, key, *args)) # Reuse the existing request, since it's equivalent. cache.destroy(request) end - nil + result end # Search for more than one instance. Should always return an array. -- cgit From cb617f20ed6e0af362937760f33f5ddc34e626ee Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Fri, 11 Apr 2008 13:53:27 -0500 Subject: Making the changes necessary to get the REST support to work with the current state of the indirection work, including using a request object and an expiration date. --- lib/puppet/indirector/rest.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index 34596cad4..26f7736f3 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -20,26 +20,26 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus network {|conn| conn.put("/#{path}", data).body } end - def find(name, options = {}) - network_result = network_fetch("#{indirection.name}/#{name}") + def find(request) + network_result = network_fetch("#{indirection.name}/#{request.key}") raise YAML.load(network_result) if exception?(network_result) indirection.model.from_yaml(network_result) end - def search(name, options = {}) - network_results = network_fetch("#{indirection.name}s/#{name}") + def search(request) + network_results = network_fetch("#{indirection.name}s/#{request.key}") raise YAML.load(network_results) if exception?(network_results) YAML.load(network_results.to_s).collect {|result| indirection.model.from_yaml(result) } end - def destroy(name, options = {}) - network_result = network_delete("#{indirection.name}/#{name}") + def destroy(request) + network_result = network_delete("#{indirection.name}/#{request.key}") raise YAML.load(network_result) if exception?(network_result) YAML.load(network_result.to_s) end - def save(obj, options = {}) - network_result = network_put("#{indirection.name}/", obj.to_yaml) + def save(request) + network_result = network_put("#{indirection.name}/", request.instance.to_yaml) raise YAML.load(network_result) if exception?(network_result) indirection.model.from_yaml(network_result) end -- cgit From d9846fc3f06f61fcb4b8806740f77747a7f6939e Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Fri, 11 Apr 2008 15:04:54 -0500 Subject: Fixishing some pending tests, including filling in the connection information. --- lib/puppet/indirector/rest.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index 26f7736f3..d33150fc2 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -5,7 +5,7 @@ require 'uri' class Puppet::Indirector::REST < Puppet::Indirector::Terminus def rest_connection_details - { :host => '127.0.0.1', :port => 34343 } + { :host => Puppet[:server], :port => Puppet[:masterport].to_i } end def network_fetch(path) @@ -47,7 +47,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus private def network(&block) - Net::HTTP.start(rest_connection_details[:host], rest_connection_details[:port]) {|conn| yield(conn) } + Net::HTTP.start(rest_connection_details[:host], rest_connection_details[:port]) {|conn| yield(conn) } end def exception?(yaml_string) -- cgit