From 10039b94c77d4543d3b256b0bbda855d57a17be1 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Fri, 12 Oct 2007 16:17:00 -0500 Subject: interim checkin of network stuffs --- lib/puppet/network/server.rb | 98 ++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 53 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/server.rb b/lib/puppet/network/server.rb index 84a71a6b4..177cce4df 100644 --- a/lib/puppet/network/server.rb +++ b/lib/puppet/network/server.rb @@ -1,66 +1,58 @@ class Puppet::Network::Server - attr_reader :server_type + attr_reader :server_type, :http_server - # which HTTP server subclass actually handles web requests of a certain type? (e.g., :rest => RESTServer) - def self.server_class_by_name(name) - klass = (name.to_s + 'Server').to_sym - const_get klass - end - - # we will actually return an instance of the Server subclass which handles the HTTP web server, instead of - # an instance of this generic Server class. A tiny bit of sleight-of-hand is necessary to make this happen. - def self.new(args = {}) - server_type = Puppet[:servertype] or raise "No servertype configuration found." - obj = self.server_class_by_name(server_type).allocate - obj.send :initialize, args.merge(:server_type => server_type) - obj - end - - def initialize(args = {}) - @routes = {} - @listening = false - @server_type = args[:server_type] - self.register(args[:handlers]) if args[:handlers] - end + def initialize(args = {}) + @server_type = Puppet[:servertype] or raise "No servertype configuration found." # e.g., WEBrick, Mongrel, etc. + @http_server_class = http_server_class_by_type(@server_type) + @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 } - end + def register(*indirections) + raise ArgumentError, "Indirection names are required." if indirections.empty? + indirections.flatten.each { |i| @routes[i.to_sym] = true } + end - def unregister(*indirections) - indirections = @routes.keys if indirections.empty? - indirections.flatten.each do |i| - raise(ArgumentError, "indirection [%s] is not known" % i) unless @routes[i.to_sym] - @routes.delete(i.to_sym) + 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 + + indirections.flatten.each do |i| + @routes.delete(i.to_sym) + end end - end - def listening? - @listening - end + def listening? + @listening + end - def listen - raise "Cannot listen -- already listening" if listening? - start_web_server - @listening = true - end + def listen + raise "Cannot listen -- already listening." if listening? + initialize_http_server + self.http_server.listen(@routes.dup) + @listening = true + end - def unlisten - raise "Cannot unlisten -- not currently listening" unless listening? - stop_web_server - @listening = false - end + def unlisten + raise "Cannot unlisten -- not currently listening." unless listening? + self.http_server.unlisten + @listening = false + end private - def start_web_server - raise NotImplementedError, "this method needs to be implemented by the actual web server (sub)class" - end - - def stop_web_server - raise NotImplementedError, "this method needs to be implemented by the actual web server (sub)class" - end + def initialize_http_server + @server = @http_server_class.new + end + + def http_server_class_by_type(kind) + # TODO: this will become Puppet::Network::HTTP::WEBrick or Puppet::Network::HTTP::Mongrel + Class.new + end end - -- cgit From e90191af9300fda00cd29d609ac80daff00332cc Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Fri, 12 Oct 2007 16:17:31 -0500 Subject: more stuff for the interim commit --- lib/puppet/network/controller.rb | 30 ++++++++++++++++++++++++++++++ lib/puppet/network/http.rb | 18 ++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 lib/puppet/network/controller.rb create mode 100644 lib/puppet/network/http.rb (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/controller.rb b/lib/puppet/network/controller.rb new file mode 100644 index 000000000..7e4cca643 --- /dev/null +++ b/lib/puppet/network/controller.rb @@ -0,0 +1,30 @@ +class Puppet::Network::Controller + def initialize(args = {}) + raise ArgumentError, ":indirection is required" unless args[:indirection] + @indirection = args[:indirection] + @klass = model_class_from_indirection_name(@indirection) + end + + def find(args = {}) + @klass.find(args) + end + + def destroy(args = {}) + @klass.destroy(args) + end + + def search(args = {}) + @klass.search(args) + end + + def save(args = {}) + instance = @klass.new(args) + instance.save + end + + private + + def model_class_from_indirection_name + Class.new # TODO : FIXME make this the indirection class + end +end diff --git a/lib/puppet/network/http.rb b/lib/puppet/network/http.rb new file mode 100644 index 000000000..c46a73159 --- /dev/null +++ b/lib/puppet/network/http.rb @@ -0,0 +1,18 @@ +class Puppet::Network::HTTP + def self.new(args = {}) + raise ArgumentError, ":server_type is required" unless args[:server_type] + obj = class_for_server_type(args[:server_type]).allocate + obj.send :initialize, args.delete_if {|k,v| k == :server_type } + obj + end + + class << self + def class_for_server_type(server_type) + Class.new + # TODO: this will end up probably: { :webrick => ... } + + end + private :class_for_server_type + end +end + -- cgit From 31384fea2263d9ee0e65312b4a0b956436022e63 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Mon, 15 Oct 2007 11:07:48 -0500 Subject: Pushing functionality down to webrick/mongrel classes now; cleanup in the base server / http server classes + specs. --- lib/puppet/network/http.rb | 20 ++++++-------------- lib/puppet/network/http/mongrel.rb | 2 ++ lib/puppet/network/http/webrick.rb | 2 ++ lib/puppet/network/server.rb | 15 +++++++-------- 4 files changed, 17 insertions(+), 22 deletions(-) create mode 100644 lib/puppet/network/http/mongrel.rb create mode 100644 lib/puppet/network/http/webrick.rb (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http.rb b/lib/puppet/network/http.rb index c46a73159..86784e50e 100644 --- a/lib/puppet/network/http.rb +++ b/lib/puppet/network/http.rb @@ -1,18 +1,10 @@ class Puppet::Network::HTTP - def self.new(args = {}) - raise ArgumentError, ":server_type is required" unless args[:server_type] - obj = class_for_server_type(args[:server_type]).allocate - obj.send :initialize, args.delete_if {|k,v| k == :server_type } - obj - end - - class << self - def class_for_server_type(server_type) - Class.new - # TODO: this will end up probably: { :webrick => ... } - - end - private :class_for_server_type + def self.server_class_by_type(kind) + return Puppet::Network::HTTP::WEBRick if kind == :webrick + return Puppet::Network::HTTP::Mongrel if kind == :mongrel + raise ArgumentError, "Unknown HTTP server name [#{kind}]" end end +require 'puppet/network/http/webrick' +require 'puppet/network/http/mongrel' diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb new file mode 100644 index 000000000..dda3c1751 --- /dev/null +++ b/lib/puppet/network/http/mongrel.rb @@ -0,0 +1,2 @@ +class Puppet::Network::HTTP::Mongrel +end diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb new file mode 100644 index 000000000..ad15261f6 --- /dev/null +++ b/lib/puppet/network/http/webrick.rb @@ -0,0 +1,2 @@ +class Puppet::Network::HTTP::WEBRick +end diff --git a/lib/puppet/network/server.rb b/lib/puppet/network/server.rb index 177cce4df..941cb9df1 100644 --- a/lib/puppet/network/server.rb +++ b/lib/puppet/network/server.rb @@ -1,9 +1,10 @@ class Puppet::Network::Server - attr_reader :server_type, :http_server + attr_reader :server_type, :http_server_class, :protocols def initialize(args = {}) @server_type = Puppet[:servertype] or raise "No servertype configuration found." # e.g., WEBrick, Mongrel, etc. @http_server_class = http_server_class_by_type(@server_type) + @protocols = [] @listening = false @routes = {} self.register(args[:handlers]) if args[:handlers] @@ -33,26 +34,24 @@ class Puppet::Network::Server def listen raise "Cannot listen -- already listening." if listening? - initialize_http_server - self.http_server.listen(@routes.dup) + http_server.listen(@routes.dup) @listening = true end def unlisten raise "Cannot unlisten -- not currently listening." unless listening? - self.http_server.unlisten + http_server.unlisten @listening = false end private - def initialize_http_server - @server = @http_server_class.new + def http_server + @http_server ||= http_server_class.new end def http_server_class_by_type(kind) - # TODO: this will become Puppet::Network::HTTP::WEBrick or Puppet::Network::HTTP::Mongrel - Class.new + Puppet::Network::HTTP.server_class_by_type(kind) end end -- cgit From ec71e05a162ec299982b90707cc16231c608997b Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Mon, 15 Oct 2007 12:04:30 -0500 Subject: More unit specs for mongrel and webrick; more code to make them work, yo. --- lib/puppet/network/http.rb | 4 ++-- lib/puppet/network/http/mongrel.rb | 19 +++++++++++++++++++ lib/puppet/network/http/webrick.rb | 21 ++++++++++++++++++++- 3 files changed, 41 insertions(+), 3 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http.rb b/lib/puppet/network/http.rb index 86784e50e..5dddad848 100644 --- a/lib/puppet/network/http.rb +++ b/lib/puppet/network/http.rb @@ -1,7 +1,7 @@ class Puppet::Network::HTTP def self.server_class_by_type(kind) - return Puppet::Network::HTTP::WEBRick if kind == :webrick - return Puppet::Network::HTTP::Mongrel if kind == :mongrel + return Puppet::Network::HTTP::WEBRick if kind.to_sym == :webrick + return Puppet::Network::HTTP::Mongrel if kind.to_sym == :mongrel raise ArgumentError, "Unknown HTTP server name [#{kind}]" end end diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index dda3c1751..dbdd72d42 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -1,2 +1,21 @@ +require 'mongrel' + class Puppet::Network::HTTP::Mongrel + def initialize(args = {}) + @listening = false + end + + def listen(args = {}) + raise ArgumentError if args.keys.empty? + raise "Mongrel server is already listening" if @listening + @server = Mongrel::HttpServer.new("0.0.0.0", "3000") + @server.run + @listening = true + end + + def unlisten + raise "Mongrel server is not listening" unless @listening + @server.graceful_shutdown + @listening = false + end end diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index ad15261f6..77e55a224 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -1,2 +1,21 @@ -class Puppet::Network::HTTP::WEBRick +require 'webrick' +require 'webrick/https' + +class Puppet::Network::HTTP::WEBRick < WEBrick::HTTPServer + def initialize(args = {}) + @listening = false + end + + def listen(args = {}) + raise ArgumentError if args.keys.empty? + raise "WEBRick server is already listening" if @listening + # TODO / FIXME: this should be moved out of the wacky Puppet global namespace! + Puppet.start + @listening = true + end + + def unlisten + raise "WEBRick server is not listening" unless @listening + shutdown + end end -- cgit From e56406f15086eb483c00a2904d8a75518412a905 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Mon, 15 Oct 2007 12:16:48 -0500 Subject: Implementing listening state tracking for webrick and mongrel. --- lib/puppet/network/http/mongrel.rb | 8 ++++++-- lib/puppet/network/http/webrick.rb | 9 +++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index dbdd72d42..49449cf59 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -7,15 +7,19 @@ class Puppet::Network::HTTP::Mongrel def listen(args = {}) raise ArgumentError if args.keys.empty? - raise "Mongrel server is already listening" if @listening + raise "Mongrel server is already listening" if listening? @server = Mongrel::HttpServer.new("0.0.0.0", "3000") @server.run @listening = true end def unlisten - raise "Mongrel server is not listening" unless @listening + raise "Mongrel server is not listening" unless listening? @server.graceful_shutdown @listening = false end + + def listening? + @listening + end end diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index 77e55a224..ffea60eba 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -8,14 +8,19 @@ class Puppet::Network::HTTP::WEBRick < WEBrick::HTTPServer def listen(args = {}) raise ArgumentError if args.keys.empty? - raise "WEBRick server is already listening" if @listening + raise "WEBRick server is already listening" if listening? # TODO / FIXME: this should be moved out of the wacky Puppet global namespace! Puppet.start @listening = true end def unlisten - raise "WEBRick server is not listening" unless @listening + raise "WEBRick server is not listening" unless listening? shutdown + @listening = false + end + + def listening? + @listening end end -- cgit From 9a179ec3a9df62c6179e7151831c4f07197cfbce Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Mon, 15 Oct 2007 12:19:08 -0500 Subject: trivial: WEBRick -> WEBrick, to be more consistent with how the WEBrick ruby classes are named. --- lib/puppet/network/http.rb | 2 +- lib/puppet/network/http/webrick.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http.rb b/lib/puppet/network/http.rb index 5dddad848..044310d8e 100644 --- a/lib/puppet/network/http.rb +++ b/lib/puppet/network/http.rb @@ -1,6 +1,6 @@ class Puppet::Network::HTTP def self.server_class_by_type(kind) - return Puppet::Network::HTTP::WEBRick if kind.to_sym == :webrick + return Puppet::Network::HTTP::WEBrick if kind.to_sym == :webrick return Puppet::Network::HTTP::Mongrel if kind.to_sym == :mongrel raise ArgumentError, "Unknown HTTP server name [#{kind}]" end diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index ffea60eba..85a329454 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -1,21 +1,21 @@ require 'webrick' require 'webrick/https' -class Puppet::Network::HTTP::WEBRick < WEBrick::HTTPServer +class Puppet::Network::HTTP::WEBrick < WEBrick::HTTPServer def initialize(args = {}) @listening = false end def listen(args = {}) raise ArgumentError if args.keys.empty? - raise "WEBRick server is already listening" if listening? + raise "WEBrick server is already listening" if listening? # TODO / FIXME: this should be moved out of the wacky Puppet global namespace! Puppet.start @listening = true end def unlisten - raise "WEBRick server is not listening" unless listening? + raise "WEBrick server is not listening" unless listening? shutdown @listening = false end -- cgit From c34efbccf1eec9957253d4fcdcb4ea9c79837ad8 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Mon, 15 Oct 2007 14:47:25 -0500 Subject: Hooking up address/port support for the various servers w/ specs. Still need to start up a webrick server w/ address + port (this is far too incestuous with Puppet lib & Puppet.start at the moment). --- lib/puppet/network/http/mongrel.rb | 6 ++++-- lib/puppet/network/http/webrick.rb | 5 ++++- lib/puppet/network/server.rb | 6 +++++- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index 49449cf59..bbba69fe3 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -6,9 +6,11 @@ class Puppet::Network::HTTP::Mongrel end def listen(args = {}) - raise ArgumentError if args.keys.empty? + raise ArgumentError, ":handlers must be specified." if !args[:handlers] or args[:handlers].keys.empty? + 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? - @server = Mongrel::HttpServer.new("0.0.0.0", "3000") + @server = Mongrel::HttpServer.new(args[:address], args[:port]) @server.run @listening = true end diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index 85a329454..c22bce938 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -7,8 +7,11 @@ class Puppet::Network::HTTP::WEBrick < WEBrick::HTTPServer end def listen(args = {}) - raise ArgumentError if args.keys.empty? + raise ArgumentError, ":handlers must be specified." if !args[:handlers] or args[:handlers].keys.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? + # TODO / FIXME: this should be moved out of the wacky Puppet global namespace! Puppet.start @listening = true diff --git a/lib/puppet/network/server.rb b/lib/puppet/network/server.rb index 941cb9df1..0541c1c3b 100644 --- a/lib/puppet/network/server.rb +++ b/lib/puppet/network/server.rb @@ -1,9 +1,13 @@ class Puppet::Network::Server - attr_reader :server_type, :http_server_class, :protocols + attr_reader :server_type, :http_server_class, :protocols, :address, :port def initialize(args = {}) @server_type = Puppet[:servertype] or raise "No servertype configuration found." # e.g., WEBrick, Mongrel, etc. @http_server_class = http_server_class_by_type(@server_type) + @address = args[:address] || Puppet[:bindaddress] || + 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 = {} -- cgit From ef8ebe0df4da0a0cd2f599308f40bd707ab18d92 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Mon, 15 Oct 2007 15:04:10 -0500 Subject: Implementing address & port support for new webrick server. --- lib/puppet/network/http/webrick.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index c22bce938..b74bf441e 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -1,7 +1,7 @@ require 'webrick' require 'webrick/https' -class Puppet::Network::HTTP::WEBrick < WEBrick::HTTPServer +class Puppet::Network::HTTP::WEBrick def initialize(args = {}) @listening = false end @@ -12,8 +12,12 @@ class Puppet::Network::HTTP::WEBrick < WEBrick::HTTPServer raise ArgumentError, ":port must be specified." unless args[:port] raise "WEBrick server is already listening" if listening? - # TODO / FIXME: this should be moved out of the wacky Puppet global namespace! + @server = WEBrick::HTTPServer.new(:BindAddress => args[:address], :Port => args[:port]) + + # TODO / FIXME is this really necessary? -- or can we do it in both mongrel and webrick? + Puppet.newservice(@server) Puppet.start + @listening = true end -- cgit From ba952029b057cb64cf28d9e4dfb5c78868a4b53f Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Mon, 15 Oct 2007 15:29:00 -0500 Subject: Partial support for building Handlers for all handler-protocol pairs. --- lib/puppet/network/http/mongrel.rb | 23 ++++++++++++++++++++++- lib/puppet/network/http/webrick.rb | 22 +++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index bbba69fe3..ab1e616b1 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -6,10 +6,17 @@ class Puppet::Network::HTTP::Mongrel end def listen(args = {}) - raise ArgumentError, ":handlers must be specified." if !args[:handlers] or args[:handlers].keys.empty? + 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? 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] + + setup_handlers + @server = Mongrel::HttpServer.new(args[:address], args[:port]) @server.run @listening = true @@ -24,4 +31,18 @@ class Puppet::Network::HTTP::Mongrel def listening? @listening end + + private + + def setup_handlers + @protocols.each do |protocol| + @handlers.each do |handler| + class_for_protocol_handler(protocol, handler).new + end + end + end + + def class_for_protocol_handler(protocol, handler) + Class.new + end end diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index b74bf441e..00d13437c 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -7,11 +7,17 @@ class Puppet::Network::HTTP::WEBrick end def listen(args = {}) - raise ArgumentError, ":handlers must be specified." if !args[:handlers] or args[:handlers].keys.empty? + 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? 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] + + setup_handlers + @server = WEBrick::HTTPServer.new(:BindAddress => args[:address], :Port => args[:port]) # TODO / FIXME is this really necessary? -- or can we do it in both mongrel and webrick? @@ -30,4 +36,18 @@ class Puppet::Network::HTTP::WEBrick def listening? @listening end + + private + + def setup_handlers + @handlers.each do |handler| + @protocols.each do |protocol| + class_for_protocol_handler(protocol, handler).new + end + end + end + + def class_for_protocol_handler(protocol, handler) + Class.new + end end -- cgit From b1d62231c587e13ad78fe1bbd292a6c9f1cb99a1 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Mon, 15 Oct 2007 23:04:24 -0500 Subject: Bringing in initial handlers for server+protocol pairs. --- lib/puppet/network/http/mongrel.rb | 16 ++++++++++------ lib/puppet/network/http/webrick.rb | 15 +++++++++------ 2 files changed, 19 insertions(+), 12 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index ab1e616b1..5b14d93c9 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -14,10 +14,10 @@ class Puppet::Network::HTTP::Mongrel @protocols = args[:protocols] @handlers = args[:handlers] - - setup_handlers - @server = Mongrel::HttpServer.new(args[:address], args[:port]) + + setup_handlers + @server.run @listening = true end @@ -37,12 +37,16 @@ class Puppet::Network::HTTP::Mongrel def setup_handlers @protocols.each do |protocol| @handlers.each do |handler| - class_for_protocol_handler(protocol, handler).new + class_for_protocol(protocol).new(:server => @server, :handler => handler) end end end - def class_for_protocol_handler(protocol, handler) - Class.new + # TODO/FIXME: need a spec which forces delegation to the real class + def class_for_protocol(protocol) + Class.new do + def initialize(args = {}) + end + end end end diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index 00d13437c..474f66e4f 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -14,12 +14,11 @@ class Puppet::Network::HTTP::WEBrick raise "WEBrick server is already listening" if listening? @protocols = args[:protocols] - @handlers = args[:handlers] + @handlers = args[:handlers] + @server = WEBrick::HTTPServer.new(:BindAddress => args[:address], :Port => args[:port]) setup_handlers - @server = WEBrick::HTTPServer.new(:BindAddress => args[:address], :Port => args[:port]) - # TODO / FIXME is this really necessary? -- or can we do it in both mongrel and webrick? Puppet.newservice(@server) Puppet.start @@ -42,12 +41,16 @@ class Puppet::Network::HTTP::WEBrick def setup_handlers @handlers.each do |handler| @protocols.each do |protocol| - class_for_protocol_handler(protocol, handler).new + class_for_protocol(protocol).new(:server => @server, :handler => handler) end end end - def class_for_protocol_handler(protocol, handler) - Class.new + # TODO/FIXME: need a spec which forces delegation to the real class + def class_for_protocol(protocol) + Class.new do + def initialize(args = {}) + end + end end end -- cgit From 099c5469bf8fd6bf1e65be1a8192c14e584e49c3 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Mon, 15 Oct 2007 23:33:12 -0500 Subject: Finish front end of delegation to server+protocol helper classes ("handlers"). --- lib/puppet/network/http/mongrel.rb | 9 +++++---- lib/puppet/network/http/mongrel/rest.rb | 4 ++++ lib/puppet/network/http/mongrel/xmlrpc.rb | 4 ++++ lib/puppet/network/http/webrick.rb | 10 +++++----- lib/puppet/network/http/webrick/rest.rb | 4 ++++ lib/puppet/network/http/webrick/xmlrpc.rb | 4 ++++ 6 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 lib/puppet/network/http/mongrel/rest.rb create mode 100644 lib/puppet/network/http/mongrel/xmlrpc.rb create mode 100644 lib/puppet/network/http/webrick/rest.rb create mode 100644 lib/puppet/network/http/webrick/xmlrpc.rb (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index 5b14d93c9..3efc465ad 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -1,4 +1,6 @@ require 'mongrel' +require 'puppet/network/http/mongrel/rest' +require 'puppet/network/http/mongrel/xmlrpc' class Puppet::Network::HTTP::Mongrel def initialize(args = {}) @@ -44,9 +46,8 @@ class Puppet::Network::HTTP::Mongrel # TODO/FIXME: need a spec which forces delegation to the real class def class_for_protocol(protocol) - Class.new do - def initialize(args = {}) - end - end + 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/rest.rb b/lib/puppet/network/http/mongrel/rest.rb new file mode 100644 index 000000000..6e454c7d9 --- /dev/null +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -0,0 +1,4 @@ +class Puppet::Network::HTTP::MongrelREST + def initialize(args = {}) + end +end diff --git a/lib/puppet/network/http/mongrel/xmlrpc.rb b/lib/puppet/network/http/mongrel/xmlrpc.rb new file mode 100644 index 000000000..92acd4f0e --- /dev/null +++ b/lib/puppet/network/http/mongrel/xmlrpc.rb @@ -0,0 +1,4 @@ +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 474f66e4f..6df7804c6 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -1,5 +1,7 @@ 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 = {}) @@ -46,11 +48,9 @@ class Puppet::Network::HTTP::WEBrick end end - # TODO/FIXME: need a spec which forces delegation to the real class def class_for_protocol(protocol) - Class.new do - def initialize(args = {}) - end - end + 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/rest.rb b/lib/puppet/network/http/webrick/rest.rb new file mode 100644 index 000000000..5e9ccfc45 --- /dev/null +++ b/lib/puppet/network/http/webrick/rest.rb @@ -0,0 +1,4 @@ +class Puppet::Network::HTTP::WEBrickREST + def initialize(args = {}) + end +end \ No newline at end of file diff --git a/lib/puppet/network/http/webrick/xmlrpc.rb b/lib/puppet/network/http/webrick/xmlrpc.rb new file mode 100644 index 000000000..793708f8a --- /dev/null +++ b/lib/puppet/network/http/webrick/xmlrpc.rb @@ -0,0 +1,4 @@ +class Puppet::Network::HTTP::WEBrickXMLRPC + def initialize(args = {}) + end +end -- cgit From ab4c7fa825e0d1f702adc215c7ff6d445d3b6559 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 16 Oct 2007 00:14:02 -0500 Subject: Minor tweaks to make the ::Server initialization a bit more robust. Fail on unknown HTTP Server types; fail fast. --- lib/puppet/network/server.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/server.rb b/lib/puppet/network/server.rb index 0541c1c3b..50e3bd686 100644 --- a/lib/puppet/network/server.rb +++ b/lib/puppet/network/server.rb @@ -1,9 +1,9 @@ class Puppet::Network::Server - attr_reader :server_type, :http_server_class, :protocols, :address, :port + attr_reader :server_type, :protocols, :address, :port def initialize(args = {}) @server_type = Puppet[:servertype] or raise "No servertype configuration found." # e.g., WEBrick, Mongrel, etc. - @http_server_class = http_server_class_by_type(@server_type) + http_server_class || raise(ArgumentError, "Could not determine HTTP Server class for server type [#{@server_type}]") @address = args[:address] || Puppet[:bindaddress] || raise(ArgumentError, "Must specify :address or configure Puppet :bindaddress.") @port = args[:port] || Puppet[:masterport] || @@ -47,6 +47,10 @@ class Puppet::Network::Server http_server.unlisten @listening = false end + + def http_server_class + http_server_class_by_type(@server_type) + end private -- cgit From c06edda4c94ef9aa685ed44d7031bb39c4a2b0cc Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 16 Oct 2007 10:15:14 -0500 Subject: First pass through initializers of {mongrel, webrick} REST handlers; hooks into Indirection to look up models from indirected names. --- lib/puppet/network/http/mongrel.rb | 4 +--- lib/puppet/network/http/mongrel/rest.rb | 14 ++++++++++++++ lib/puppet/network/http/webrick.rb | 6 ++---- lib/puppet/network/http/webrick/rest.rb | 14 ++++++++++++++ 4 files changed, 31 insertions(+), 7 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index 3efc465ad..bec94ac13 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -38,9 +38,7 @@ class Puppet::Network::HTTP::Mongrel def setup_handlers @protocols.each do |protocol| - @handlers.each do |handler| - class_for_protocol(protocol).new(:server => @server, :handler => handler) - end + class_for_protocol(protocol).new(:server => @server, :handlers => @handlers) end end diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index 6e454c7d9..34f1d8f90 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -1,4 +1,18 @@ class Puppet::Network::HTTP::MongrelREST def initialize(args = {}) + raise ArgumentError unless args[:server] + raise ArgumentError if !args[:handlers] or args[:handlers].empty? + + @models = {} + args[:handlers].each do |handler| + @models[handler] = find_model_for_handler(handler) + end + end + + private + + def find_model_for_handler(handler) + Puppet::Indirector::Indirection.model(handler) || + raise(ArgumentError, "Cannot locate indirection [#{handler}].") end end diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index 6df7804c6..21d191d06 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -41,10 +41,8 @@ class Puppet::Network::HTTP::WEBrick private def setup_handlers - @handlers.each do |handler| - @protocols.each do |protocol| - class_for_protocol(protocol).new(:server => @server, :handler => handler) - end + @protocols.each do |protocol| + class_for_protocol(protocol).new(:server => @server, :handlers => @handlers) end end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index 5e9ccfc45..f70f2030f 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -1,4 +1,18 @@ class Puppet::Network::HTTP::WEBrickREST def initialize(args = {}) + raise ArgumentError unless args[:server] + raise ArgumentError if !args[:handlers] or args[:handlers].empty? + + @models = {} + args[:handlers].each do |handler| + @models[handler] = find_model_for_handler(handler) + end + end + + private + + def find_model_for_handler(handler) + Puppet::Indirector::Indirection.model(handler) || + raise(ArgumentError, "Cannot locate indirection [#{handler}].") end end \ No newline at end of file -- cgit From 3c370b3570d39c18799085793e083898cda72e68 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 16 Oct 2007 10:44:02 -0500 Subject: Going back to each server+protocol object being responsible for only one indirection, as the REST vs. XMLRPC models are different enough that the object must register itself on initialization and handle the request when it comes in. --- lib/puppet/network/http/mongrel.rb | 4 +++- lib/puppet/network/http/mongrel/rest.rb | 8 ++------ lib/puppet/network/http/webrick.rb | 4 +++- lib/puppet/network/http/webrick/rest.rb | 8 ++------ 4 files changed, 10 insertions(+), 14 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index bec94ac13..3efc465ad 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -38,7 +38,9 @@ class Puppet::Network::HTTP::Mongrel def setup_handlers @protocols.each do |protocol| - class_for_protocol(protocol).new(:server => @server, :handlers => @handlers) + @handlers.each do |handler| + class_for_protocol(protocol).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 34f1d8f90..0b2c43dfe 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -1,12 +1,8 @@ class Puppet::Network::HTTP::MongrelREST def initialize(args = {}) raise ArgumentError unless args[:server] - raise ArgumentError if !args[:handlers] or args[:handlers].empty? - - @models = {} - args[:handlers].each do |handler| - @models[handler] = find_model_for_handler(handler) - end + raise ArgumentError unless @handler = args[:handler] + @model = find_model_for_handler(@handler) end private diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index 21d191d06..53aa2e99b 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -42,7 +42,9 @@ class Puppet::Network::HTTP::WEBrick def setup_handlers @protocols.each do |protocol| - class_for_protocol(protocol).new(:server => @server, :handlers => @handlers) + @handlers.each do |handler| + class_for_protocol(protocol).new(:server => @server, :handler => handler) + end end end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index f70f2030f..497fa26cc 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -1,12 +1,8 @@ class Puppet::Network::HTTP::WEBrickREST def initialize(args = {}) raise ArgumentError unless args[:server] - raise ArgumentError if !args[:handlers] or args[:handlers].empty? - - @models = {} - args[:handlers].each do |handler| - @models[handler] = find_model_for_handler(handler) - end + raise ArgumentError unless @handler = args[:handler] + @model = find_model_for_handler(@handler) end private -- cgit From b8c877c121f6b376cd44b13cb90d69c41d0fb004 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 16 Oct 2007 11:13:17 -0500 Subject: Registration now built for {webrick,mongrel} REST handlers. --- lib/puppet/network/http/mongrel/rest.rb | 10 ++++++++-- lib/puppet/network/http/webrick/rest.rb | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index 0b2c43dfe..452dafa85 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -1,12 +1,18 @@ class Puppet::Network::HTTP::MongrelREST def initialize(args = {}) - raise ArgumentError unless args[:server] + raise ArgumentError unless @server = args[:server] raise ArgumentError unless @handler = args[:handler] - @model = find_model_for_handler(@handler) + register_handler end private + def register_handler + @model = find_model_for_handler(@handler) + @server.register('/' + @handler.to_s, self) + @server.register('/' + @handler.to_s + 's', self) + end + def find_model_for_handler(handler) Puppet::Indirector::Indirection.model(handler) || raise(ArgumentError, "Cannot locate indirection [#{handler}].") diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index 497fa26cc..7b9a3912b 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -1,11 +1,17 @@ class Puppet::Network::HTTP::WEBrickREST def initialize(args = {}) - raise ArgumentError unless args[:server] + raise ArgumentError unless @server = args[:server] raise ArgumentError unless @handler = args[:handler] - @model = find_model_for_handler(@handler) + register_handler end private + + def register_handler + @model = find_model_for_handler(@handler) + @server.mount('/' + @handler.to_s, self) + @server.mount('/' + @handler.to_s + 's', self) + end def find_model_for_handler(handler) Puppet::Indirector::Indirection.model(handler) || -- cgit From 6ab78f62ee589e542fd653a54109c0f5141ea026 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 16 Oct 2007 13:24:58 -0500 Subject: Inlined the controller, eliminating a class. Mongrel+REST has the right bits for request handling prior to the encode/decode/exception-handling bits. Refactored to make the common logic extractable to a base class. --- lib/puppet/network/controller.rb | 30 ---------------------- lib/puppet/network/http/mongrel/rest.rb | 45 ++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 33 deletions(-) delete mode 100644 lib/puppet/network/controller.rb (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/controller.rb b/lib/puppet/network/controller.rb deleted file mode 100644 index 7e4cca643..000000000 --- a/lib/puppet/network/controller.rb +++ /dev/null @@ -1,30 +0,0 @@ -class Puppet::Network::Controller - def initialize(args = {}) - raise ArgumentError, ":indirection is required" unless args[:indirection] - @indirection = args[:indirection] - @klass = model_class_from_indirection_name(@indirection) - end - - def find(args = {}) - @klass.find(args) - end - - def destroy(args = {}) - @klass.destroy(args) - end - - def search(args = {}) - @klass.search(args) - end - - def save(args = {}) - instance = @klass.new(args) - instance.save - end - - private - - def model_class_from_indirection_name - Class.new # TODO : FIXME make this the indirection class - end -end diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index 452dafa85..f9a6e3796 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -5,16 +5,55 @@ class Puppet::Network::HTTP::MongrelREST register_handler end + # handle an HTTP request coming from Mongrel + def process(request, response) + return @model.find if get?(request) and singular?(request) + return @model.search if get?(request) and plural?(request) + return @model.destroy if delete?(request) and singular?(request) + return @model.new.save if put?(request) and singular?(request) + raise ArgumentError, "Did not understand HTTP #{http_method(request)} request for '#{path(request)}'" + # TODO: here, raise an exception, or do some defaulting or something + end + private + def find_model_for_handler(handler) + Puppet::Indirector::Indirection.model(handler) || + raise(ArgumentError, "Cannot locate indirection [#{handler}].") + end + + def get?(request) + http_method(request) == 'GET' + end + + def put?(request) + http_method(request) == 'PUT' + end + + def delete?(request) + http_method(request) == 'DELETE' + end + + def singular?(request) + %r{/#{@handler.to_s}$}.match(path(request)) + end + + def plural?(request) + %r{/#{@handler.to_s}s$}.match(path(request)) + end + def register_handler @model = find_model_for_handler(@handler) @server.register('/' + @handler.to_s, self) @server.register('/' + @handler.to_s + 's', self) end - def find_model_for_handler(handler) - Puppet::Indirector::Indirection.model(handler) || - raise(ArgumentError, "Cannot locate indirection [#{handler}].") + def http_method(request) + request.params[Mongrel::Const::REQUEST_METHOD] end + + def path(request) + request.params[Mongrel::Const::REQUEST_PATH] + end + end -- cgit From 2a497fff66a7827059b712e84dcaff171ccab6be Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 16 Oct 2007 13:57:56 -0500 Subject: Refactored to use a Handler base class for server+protocol handlers. Finally eliminated dependency on Puppet.start, etc., from WEBrick HTTP server class. {webrick,mongrel}+REST now support request handling uniformly; need encode/decode next. --- lib/puppet/network/http/handler.rb | 57 +++++++++++++++++++++++++++++++++ lib/puppet/network/http/mongrel/rest.rb | 47 +++------------------------ lib/puppet/network/http/webrick.rb | 9 ++---- lib/puppet/network/http/webrick/rest.rb | 21 +++++++----- 4 files changed, 76 insertions(+), 58 deletions(-) create mode 100644 lib/puppet/network/http/handler.rb (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb new file mode 100644 index 000000000..54cec417b --- /dev/null +++ b/lib/puppet/network/http/handler.rb @@ -0,0 +1,57 @@ +class Puppet::Network::HTTP::Handler + def initialize(args = {}) + raise ArgumentError unless @server = args[:server] + raise ArgumentError unless @handler = args[:handler] + register_handler + end + + # handle an HTTP request coming from Mongrel + def process(request, response) + return @model.find if get?(request) and singular?(request) + return @model.search if get?(request) and plural?(request) + return @model.destroy if delete?(request) and singular?(request) + return @model.new.save if put?(request) and singular?(request) + raise ArgumentError, "Did not understand HTTP #{http_method(request)} request for '#{path(request)}'" + end + + private + + def find_model_for_handler(handler) + Puppet::Indirector::Indirection.model(handler) || + raise(ArgumentError, "Cannot locate indirection [#{handler}].") + end + + def get?(request) + http_method(request) == 'GET' + end + + def put?(request) + http_method(request) == 'PUT' + end + + def delete?(request) + http_method(request) == 'DELETE' + end + + def singular?(request) + %r{/#{@handler.to_s}$}.match(path(request)) + end + + def plural?(request) + %r{/#{@handler.to_s}s$}.match(path(request)) + end + + # methods specific to a given web server + + def register_handler + raise UnimplementedError + end + + def http_method(request) + raise UnimplementedError + end + + def path(request) + raise UnimplementedError + end +end diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index f9a6e3796..8f3de957e 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -1,47 +1,9 @@ -class Puppet::Network::HTTP::MongrelREST - def initialize(args = {}) - raise ArgumentError unless @server = args[:server] - raise ArgumentError unless @handler = args[:handler] - register_handler - end - - # handle an HTTP request coming from Mongrel - def process(request, response) - return @model.find if get?(request) and singular?(request) - return @model.search if get?(request) and plural?(request) - return @model.destroy if delete?(request) and singular?(request) - return @model.new.save if put?(request) and singular?(request) - raise ArgumentError, "Did not understand HTTP #{http_method(request)} request for '#{path(request)}'" - # TODO: here, raise an exception, or do some defaulting or something - end - +require 'puppet/network/http/handler' + +class Puppet::Network::HTTP::MongrelREST < Puppet::Network::HTTP::Handler + private - def find_model_for_handler(handler) - Puppet::Indirector::Indirection.model(handler) || - raise(ArgumentError, "Cannot locate indirection [#{handler}].") - end - - def get?(request) - http_method(request) == 'GET' - end - - def put?(request) - http_method(request) == 'PUT' - end - - def delete?(request) - http_method(request) == 'DELETE' - end - - def singular?(request) - %r{/#{@handler.to_s}$}.match(path(request)) - end - - def plural?(request) - %r{/#{@handler.to_s}s$}.match(path(request)) - end - def register_handler @model = find_model_for_handler(@handler) @server.register('/' + @handler.to_s, self) @@ -55,5 +17,4 @@ class Puppet::Network::HTTP::MongrelREST def path(request) request.params[Mongrel::Const::REQUEST_PATH] end - end diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index 53aa2e99b..c4b2ed3c6 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -18,19 +18,14 @@ class Puppet::Network::HTTP::WEBrick @protocols = args[:protocols] @handlers = args[:handlers] @server = WEBrick::HTTPServer.new(:BindAddress => args[:address], :Port => args[:port]) - setup_handlers - - # TODO / FIXME is this really necessary? -- or can we do it in both mongrel and webrick? - Puppet.newservice(@server) - Puppet.start - + @server.start @listening = true end def unlisten raise "WEBrick server is not listening" unless listening? - shutdown + @server.shutdown @listening = false end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index 7b9a3912b..cefffd76d 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -1,8 +1,10 @@ -class Puppet::Network::HTTP::WEBrickREST - def initialize(args = {}) - raise ArgumentError unless @server = args[:server] - raise ArgumentError unless @handler = args[:handler] - register_handler +require 'puppet/network/http/handler' + +class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler + + # 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 @@ -13,8 +15,11 @@ class Puppet::Network::HTTP::WEBrickREST @server.mount('/' + @handler.to_s + 's', self) end - def find_model_for_handler(handler) - Puppet::Indirector::Indirection.model(handler) || - raise(ArgumentError, "Cannot locate indirection [#{handler}].") + def http_method(request) + request.request_method + end + + def path(request) + request.path end end \ No newline at end of file -- cgit From abbc824ff4a565f0a0f1362b779252e876b86168 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 16 Oct 2007 14:04:38 -0500 Subject: Tweak to move model lookup functionality into the Handler base class where it belongs. Robustifying the request sanitization a bit more. --- lib/puppet/network/http/handler.rb | 1 + lib/puppet/network/http/mongrel/rest.rb | 1 - lib/puppet/network/http/webrick/rest.rb | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 54cec417b..77df113e6 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -2,6 +2,7 @@ class Puppet::Network::HTTP::Handler def initialize(args = {}) raise ArgumentError unless @server = args[:server] raise ArgumentError unless @handler = args[:handler] + @model = find_model_for_handler(@handler) register_handler end diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index 8f3de957e..4c795481b 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -5,7 +5,6 @@ class Puppet::Network::HTTP::MongrelREST < Puppet::Network::HTTP::Handler private def register_handler - @model = find_model_for_handler(@handler) @server.register('/' + @handler.to_s, self) @server.register('/' + @handler.to_s + 's', self) end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index cefffd76d..ed29cfb75 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -10,7 +10,6 @@ class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler private def register_handler - @model = find_model_for_handler(@handler) @server.mount('/' + @handler.to_s, self) @server.mount('/' + @handler.to_s + 's', self) end -- cgit From 216dd8c47ea42338c2dee0bf6528cdd7e37e0028 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 16 Oct 2007 15:38:41 -0500 Subject: Refactoring, argument processing for model methods. --- lib/puppet/network/http/handler.rb | 42 +++++++++++++++++++++++++++------ lib/puppet/network/http/mongrel/rest.rb | 10 +++++++- lib/puppet/network/http/webrick/rest.rb | 10 +++++++- 3 files changed, 53 insertions(+), 9 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 77df113e6..fb7b5c323 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -8,15 +8,35 @@ class Puppet::Network::HTTP::Handler # handle an HTTP request coming from Mongrel def process(request, response) - return @model.find if get?(request) and singular?(request) - return @model.search if get?(request) and plural?(request) - return @model.destroy if delete?(request) and singular?(request) - return @model.new.save if put?(request) and singular?(request) + return do_find(request, response) if get?(request) and singular?(request) + return do_search(request, response) if get?(request) and plural?(request) + return do_destroy(request, response) if delete?(request) and singular?(request) + return do_save(request, response) if put?(request) and singular?(request) raise ArgumentError, "Did not understand HTTP #{http_method(request)} request for '#{path(request)}'" end private + def do_find(request, response) + key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]") + @model.find(key) + end + + def do_search(request, response) + @model.search + end + + def do_destroy(request, response) + key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]") + @model.destroy(key) + end + + def do_save(request, response) + data = body(request) + raise ArgumentError, "No data to save" if !data or data.empty? + @model.new.save(:data => data) + end + def find_model_for_handler(handler) Puppet::Indirector::Indirection.model(handler) || raise(ArgumentError, "Cannot locate indirection [#{handler}].") @@ -45,14 +65,22 @@ class Puppet::Network::HTTP::Handler # methods specific to a given web server def register_handler - raise UnimplementedError + raise NotImplementedError end def http_method(request) - raise UnimplementedError + raise NotImplementedError end def path(request) - raise UnimplementedError + raise NotImplementedError end + + def request_key(request) + raise NotImplementedError + end + + def body(request) + raise NotImplementedError + end end diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index 4c795481b..f7807b19f 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -14,6 +14,14 @@ class Puppet::Network::HTTP::MongrelREST < Puppet::Network::HTTP::Handler end def path(request) - request.params[Mongrel::Const::REQUEST_PATH] + '/' + request.params[Mongrel::Const::REQUEST_PATH].split('/')[1] + end + + def request_key(request) + request.params[Mongrel::Const::REQUEST_PATH].split('/')[2] + end + + def body(request) + request.body end end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index ed29cfb75..bfcd0784d 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -19,6 +19,14 @@ class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler end def path(request) - request.path + '/' + request.path.split('/')[1] + end + + def request_key(request) + request.path.split('/')[2] + end + + def body(request) + request.body end end \ No newline at end of file -- cgit From 6cd0f371065da901d8cc3143d8859a389ca87582 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 16 Oct 2007 15:52:41 -0500 Subject: Make it possible to run all tests even if mongrel isn't installed. Shouldn't "confine" produce some output when running spec? Who knows. --- lib/puppet/network/http/mongrel.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index 3efc465ad..8ea669531 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -1,4 +1,5 @@ -require 'mongrel' +require 'mongrel' if Puppet.features.mongrel? + require 'puppet/network/http/mongrel/rest' require 'puppet/network/http/mongrel/xmlrpc' -- cgit From ce349683b76ab9d21f4d89e2ec818c0755848a1d Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 16 Oct 2007 15:56:03 -0500 Subject: Make the actual runtime be more robust when mongrel is not installed. --- lib/puppet/network/http.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http.rb b/lib/puppet/network/http.rb index 044310d8e..062c67c71 100644 --- a/lib/puppet/network/http.rb +++ b/lib/puppet/network/http.rb @@ -1,7 +1,10 @@ class Puppet::Network::HTTP def self.server_class_by_type(kind) return Puppet::Network::HTTP::WEBrick if kind.to_sym == :webrick - return Puppet::Network::HTTP::Mongrel if kind.to_sym == :mongrel + if kind.to_sym == :mongrel + raise ArgumentError, "Mongrel is not installed on this platform" unless Puppet.features.mongrel? + return Puppet::Network::HTTP::Mongrel + end raise ArgumentError, "Unknown HTTP server name [#{kind}]" end end -- cgit From 705f76fa1d9a95c54560a82e68c1c47b27755361 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 16 Oct 2007 18:08:18 -0500 Subject: Argument passing now supported on {webrick,mongrel}+REST. --- lib/puppet/network/http/handler.rb | 16 ++++++++++++---- lib/puppet/network/http/mongrel/rest.rb | 4 ++++ lib/puppet/network/http/webrick/rest.rb | 4 ++++ 3 files changed, 20 insertions(+), 4 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index fb7b5c323..1f63024d6 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -19,22 +19,26 @@ class Puppet::Network::HTTP::Handler def do_find(request, response) key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]") - @model.find(key) + args = params(request) + @model.find(key, args) end def do_search(request, response) - @model.search + args = params(request) + @model.search(args) end def do_destroy(request, response) key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]") - @model.destroy(key) + args = params(request) + @model.destroy(key, args) end def do_save(request, response) data = body(request) raise ArgumentError, "No data to save" if !data or data.empty? - @model.new.save(:data => data) + args = params(request) + @model.new.save(args.merge(:data => data)) end def find_model_for_handler(handler) @@ -83,4 +87,8 @@ class Puppet::Network::HTTP::Handler def body(request) raise NotImplementedError end + + def params(request) + raise NotImplementedError + end end diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index f7807b19f..d87f9c733 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -24,4 +24,8 @@ class Puppet::Network::HTTP::MongrelREST < Puppet::Network::HTTP::Handler def body(request) request.body end + + def params(request) + Mongrel::HttpRequest.query_parse(request.params["QUERY_STRING"]) + end end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index bfcd0784d..33b1ad8dc 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -29,4 +29,8 @@ class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler def body(request) request.body end + + def params(request) + request.query + end end \ No newline at end of file -- cgit From d2b891f6e3b1460602a0056b1b9dc85028c989e1 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Wed, 17 Oct 2007 11:37:21 -0500 Subject: More specs, fleshing out the returns from REST --- lib/puppet/network/http/handler.rb | 8 ++++++-- lib/puppet/network/http/mongrel/rest.rb | 5 +++++ lib/puppet/network/http/webrick/rest.rb | 4 ++++ 3 files changed, 15 insertions(+), 2 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 1f63024d6..0d4be3a8d 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -20,12 +20,12 @@ class Puppet::Network::HTTP::Handler def do_find(request, response) key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]") args = params(request) - @model.find(key, args) + encode_result(request, response, @model.find(key, args)) end def do_search(request, response) args = params(request) - @model.search(args) + encode_result(request, response, @model.search(args)) end def do_destroy(request, response) @@ -91,4 +91,8 @@ class Puppet::Network::HTTP::Handler def params(request) raise NotImplementedError end + + def encode_result(request, response, result) + raise NotImplementedError + end end diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index d87f9c733..0d29a822e 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -28,4 +28,9 @@ class Puppet::Network::HTTP::MongrelREST < Puppet::Network::HTTP::Handler def params(request) Mongrel::HttpRequest.query_parse(request.params["QUERY_STRING"]) end + + def encode_result(request, response, result) + response.start(200) do |head, body| + end + end end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index 33b1ad8dc..1475ed781 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -33,4 +33,8 @@ class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler def params(request) request.query end + + def encode_result(request, response, result) + result + end end \ No newline at end of file -- cgit From d28a9041039860beb9e19da267bbad40ecebf8f1 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 23 Oct 2007 11:12:22 -0500 Subject: REST handlers now properly returning 200 status on success. --- lib/puppet/network/http/handler.rb | 4 ++-- lib/puppet/network/http/webrick/rest.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 4365fffca..9b21946c7 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -31,14 +31,14 @@ class Puppet::Network::HTTP::Handler def do_destroy(request, response) key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]") args = params(request) - @model.destroy(key, args) + encode_result(request, response, @model.destroy(key, args)) end def do_save(request, response) data = body(request) raise ArgumentError, "No data to save" if !data or data.empty? args = params(request) - @model.new.save(args.merge(:data => data)) + encode_result(request, response, @model.new.save(args.merge(:data => data))) end def find_model_for_handler(handler) diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index 1475ed781..d30f9318b 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -35,6 +35,6 @@ class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler end def encode_result(request, response, result) - result + response.status = 200 end end \ No newline at end of file -- cgit From e7bfe0bf9b525d6216cbb24be99357d33c0b87ec Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 23 Oct 2007 12:09:05 -0500 Subject: Finish serializing successful results (via calls to to_yaml, etc.) for REST handlers. Refactor request building in REST handler specs. --- lib/puppet/network/http/handler.rb | 14 ++++++++++---- lib/puppet/network/http/mongrel/rest.rb | 1 + lib/puppet/network/http/webrick/rest.rb | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 9b21946c7..2a537c767 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -20,25 +20,31 @@ class Puppet::Network::HTTP::Handler def do_find(request, response) key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]") args = params(request) - encode_result(request, response, @model.find(key, args)) + result = @model.find(key, args).to_yaml + encode_result(request, response, result) end def do_search(request, response) args = params(request) - encode_result(request, response, @model.search(args)) + 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) - encode_result(request, response, @model.destroy(key, args)) + result = @model.destroy(key, args) + encode_result(request, response, YAML.dump(result)) end def do_save(request, response) data = body(request) raise ArgumentError, "No data to save" if !data or data.empty? args = params(request) - encode_result(request, response, @model.new.save(args.merge(:data => data))) + obj = @model.new + result = obj.save(args.merge(:data => data)).to_yaml + encode_result(request, response, result) end def find_model_for_handler(handler) diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index 0d29a822e..f22b4c4c9 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -31,6 +31,7 @@ class Puppet::Network::HTTP::MongrelREST < Puppet::Network::HTTP::Handler def encode_result(request, response, result) response.start(200) do |head, body| + body.write(result) end end end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index d30f9318b..8782df14f 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -36,5 +36,6 @@ class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler def encode_result(request, response, result) response.status = 200 + response.body = result end end \ No newline at end of file -- cgit From 54fc80d5de7b881adca06c85206fb700f4278a73 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Tue, 23 Oct 2007 12:32:45 -0500 Subject: Exceptions on requests are now captured, exceptions are serialized, and exception text is passed back via REST. --- lib/puppet/network/http/handler.rb | 8 +++++++- lib/puppet/network/http/mongrel/rest.rb | 4 ++-- lib/puppet/network/http/webrick/rest.rb | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 2a537c767..172939538 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -13,6 +13,8 @@ class Puppet::Network::HTTP::Handler return do_destroy(request, response) if delete?(request) and singular?(request) return do_save(request, response) if put?(request) and singular?(request) raise ArgumentError, "Did not understand HTTP #{http_method(request)} request for '#{path(request)}'" + rescue Exception => e + return do_exception(request, response, e) end private @@ -47,6 +49,10 @@ class Puppet::Network::HTTP::Handler encode_result(request, response, result) end + def do_exception(request, response, exception, status=404) + encode_result(request, response, exception.to_s, status) + end + def find_model_for_handler(handler) Puppet::Indirector::Indirection.model(handler) || raise(ArgumentError, "Cannot locate indirection [#{handler}].") @@ -98,7 +104,7 @@ class Puppet::Network::HTTP::Handler raise NotImplementedError end - def encode_result(request, response, result) + def encode_result(request, response, result, status = 200) raise NotImplementedError end end diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index f22b4c4c9..db63613ab 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -29,8 +29,8 @@ class Puppet::Network::HTTP::MongrelREST < Puppet::Network::HTTP::Handler Mongrel::HttpRequest.query_parse(request.params["QUERY_STRING"]) end - def encode_result(request, response, result) - response.start(200) do |head, body| + def encode_result(request, response, result, status = 200) + response.start(status) do |head, body| body.write(result) end end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index 8782df14f..dd0c84d61 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -34,8 +34,8 @@ class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler request.query end - def encode_result(request, response, result) - response.status = 200 + def encode_result(request, response, result, status = 200) + response.status = status response.body = result end end \ No newline at end of file -- cgit From c7b36b76f1319ee18efee8ec1bdf08825cb66f81 Mon Sep 17 00:00:00 2001 From: Rick Bradley Date: Fri, 26 Oct 2007 15:23:51 -0500 Subject: One significant step closer to getting autotest running properly on the Puppet specs. Created a spec/lib/monkey_patches/ directory for holding patches to RSpec functionality. Extraced 'confine' and 'runnable?' support from the local copy of RSpec (spec/lib/spec/) and now load them from the monkey_patches/ directory. Fixed a bad include in one of the specs. Made it possible for the gem-installed spec binary (which autotest calls) to be used with Puppet. Imported the Autotest::Rspec class, created a PuppetRspec autotest class, added a discovery.rb file for autotest to pick these up. Autotest still has the following problems: * it needs to be run with the proper include path: % ruby -I spec/lib/ `which autotest` * the patterns in our custom autotest handler (puppet_rspec) aren't yet fully specified (they only recognize changes in our spec files, not changes in the puppet libs which they are testing) --- lib/puppet/network/http/handler.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 172939538..773381c8d 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -29,8 +29,7 @@ class Puppet::Network::HTTP::Handler def do_search(request, response) args = params(request) result = @model.search(args).collect {|obj| obj.to_yaml } - encode_result(request, response, result) - + encode_result(request, response, result) end def do_destroy(request, response) -- cgit From 72510bfaa65e97f4eaaf246ef8f1c155716967b6 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Mon, 12 Nov 2007 22:08:44 -0600 Subject: Fixing #800 by refactoring how configurations are retrieved from the server. The real problem was getting all of the validation done before any caching, which required a good bit more refactoring than I expected. In actuality, this commit is relatively small even though it covers many files; most of the changes just make the code clearer or shorter. --- lib/puppet/network/client/master.rb | 171 +++++++++++++++-------------------- lib/puppet/network/handler/runner.rb | 2 +- 2 files changed, 74 insertions(+), 99 deletions(-) (limited to 'lib/puppet/network') diff --git a/lib/puppet/network/client/master.rb b/lib/puppet/network/client/master.rb index 5408cabe4..ea351ddc3 100644 --- a/lib/puppet/network/client/master.rb +++ b/lib/puppet/network/client/master.rb @@ -139,63 +139,57 @@ class Puppet::Network::Client::Master < Puppet::Network::Client facts = self.class.facts end - if self.configuration or FileTest.exists?(self.cachefile) - if self.fresh?(facts) - Puppet.info "Config is up to date" - if self.configuration - return - end - if oldtext = self.retrievecache - begin - @configuration = YAML.load(oldtext).to_configuration - rescue => detail - Puppet.warning "Could not load cached configuration: %s" % detail - end - return - end - end - end - Puppet.debug("getting config") + raise Puppet::Network::ClientError.new("Could not retrieve any facts") unless facts.length > 0 # Retrieve the plugins. - if Puppet[:pluginsync] - getplugins() - end + getplugins() if Puppet[:pluginsync] - unless facts.length > 0 - raise Puppet::Network::ClientError.new( - "Could not retrieve any facts" - ) + if (self.configuration or FileTest.exist?(self.cachefile)) and self.fresh?(facts) + Puppet.info "Configuration is up to date" + return if use_cached_config end - unless objects = get_actual_config(facts) - @configuration = nil + Puppet.debug("Retrieving configuration") + + # If we can't retrieve the configuration, just return, which will either + # fail, or use the in-memory configuration. + unless yaml_objects = get_actual_config(facts) + use_cached_config(true) return end - unless objects.is_a?(Puppet::TransBucket) - raise NetworkClientError, - "Invalid returned objects of type %s" % objects.class + begin + objects = YAML.load(yaml_objects) + rescue => detail + msg = "Configuration could not be translated from yaml" + msg += "; using cached configuration" if use_cached_config(true) + Puppet.warning msg + return end self.setclasses(objects.classes) # Clear all existing objects, so we can recreate our stack. - if self.configuration - clear() - end + clear() if self.configuration # Now convert the objects to a puppet configuration graph. - @configuration = objects.to_configuration + begin + @configuration = objects.to_configuration + rescue => detail + clear() + puts detail.backtrace if Puppet[:trace] + msg = "Configuration could not be instantiated: %s" % detail + msg += "; using cached configuration" if use_cached_config(true) + Puppet.warning msg + return + end - if @configuration.nil? - raise Puppet::Error, "Configuration could not be processed" + if ! @configuration.from_cache + self.cache(yaml_objects) end # Keep the state database up to date. @configuration.host_config = true - - return @configuration end # A simple proxy method, so it's easy to test. @@ -270,11 +264,9 @@ class Puppet::Network::Client::Master < Puppet::Network::Client Puppet.err "Could not retrieve configuration: %s" % detail end - if defined? @configuration and @configuration + if self.configuration @configuration.retrieval_duration = duration - unless @local - Puppet.notice "Starting configuration run" - end + Puppet.notice "Starting configuration run" unless @local benchmark(:notice, "Finished configuration run") do @configuration.apply(options) end @@ -500,34 +492,16 @@ class Puppet::Network::Client::Master < Puppet::Network::Client # Actually retrieve the configuration, either from the server or from a # local master. def get_actual_config(facts) - if @local - return get_local_config(facts) - else - begin - Timeout::timeout(self.class.timeout) do - return get_remote_config(facts) - end - rescue Timeout::Error - Puppet.err "Configuration retrieval timed out" - return nil + begin + Timeout::timeout(self.class.timeout) do + return get_remote_config(facts) end + rescue Timeout::Error + Puppet.err "Configuration retrieval timed out" + return nil end end - # Retrieve a configuration from a local master. - def get_local_config(facts) - # If we're local, we don't have to do any of the conversion - # stuff. - objects = @driver.getconfig(facts, "yaml") - @compile_time = Time.now - - if objects == "" - raise Puppet::Error, "Could not retrieve configuration" - end - - return objects - end - # Retrieve a config from a remote master. def get_remote_config(facts) textobjects = "" @@ -545,45 +519,18 @@ class Puppet::Network::Client::Master < Puppet::Network::Client end rescue => detail - puts detail.backtrace Puppet.err "Could not retrieve configuration: %s" % detail - - unless Puppet[:usecacheonfailure] - @configuration = nil - Puppet.warning "Not using cache on failed configuration" - return - end + return nil end end - fromcache = false - if textobjects == "" - unless textobjects = self.retrievecache - raise Puppet::Error.new( - "Cannot connect to server and there is no cached configuration" - ) - end - Puppet.warning "Could not get config; using cached copy" - fromcache = true - else - @compile_time = Time.now - Puppet::Util::Storage.cache(:configuration)[:facts] = facts - Puppet::Util::Storage.cache(:configuration)[:compile_time] = @compile_time - end + return nil if textobjects == "" - begin - objects = YAML.load(textobjects) - rescue => detail - raise Puppet::Error, - "Could not understand configuration: %s" % - detail.to_s - end + @compile_time = Time.now + Puppet::Util::Storage.cache(:configuration)[:facts] = facts + Puppet::Util::Storage.cache(:configuration)[:compile_time] = @compile_time - if @cache and ! fromcache - self.cache(textobjects) - end - - return objects + return textobjects end def lockfile @@ -609,4 +556,32 @@ class Puppet::Network::Client::Master < Puppet::Network::Client Puppet.info "Sleeping for %s seconds (splay is enabled)" % time sleep(time) end + + private + + # Use our cached config, optionally specifying whether this is + # necessary because of a failure. + def use_cached_config(because_of_failure = false) + return true if self.configuration + + if because_of_failure and ! Puppet[:usecacheonfailure] + @configuration = nil + Puppet.warning "Not using cache on failed configuration" + return false + end + + return false unless oldtext = self.retrievecache + + begin + @configuration = YAML.load(oldtext).to_configuration + @configuration.from_cache = true + @configuration.host_config = true + rescue => detail + puts detail.backtrace if Puppet[:trace] + Puppet.warning "Could not load cached configuration: %s" % detail + clear + return false + end + return true + end end diff --git a/lib/puppet/network/handler/runner.rb b/lib/puppet/network/handler/runner.rb index a8d0da9ce..c97e4791a 100755 --- a/lib/puppet/network/handler/runner.rb +++ b/lib/puppet/network/handler/runner.rb @@ -43,7 +43,7 @@ class Puppet::Network::Handler end if ignoreschedules - msg += " without schedules" + msg += " ignoring schedules" end Puppet.notice msg -- cgit