diff options
| author | Christian Hofstaedtler <hofstaedtler@inqnet.at> | 2009-04-28 12:29:20 +0000 |
|---|---|---|
| committer | James Turnbull <james@lovedthanlost.net> | 2009-05-02 09:13:29 +1000 |
| commit | d6be4e1206e9285dee9fc4d8cde9608c029d4001 (patch) | |
| tree | 8027f46a38089b893faa8d9e342cacec65333dfb /lib/puppet/network/http | |
| parent | 6e01e7ab403d090f29f13c938ca5b19930c4b408 (diff) | |
| download | puppet-d6be4e1206e9285dee9fc4d8cde9608c029d4001.tar.gz puppet-d6be4e1206e9285dee9fc4d8cde9608c029d4001.tar.xz puppet-d6be4e1206e9285dee9fc4d8cde9608c029d4001.zip | |
Add XMLRPC compatibility for Rack
Diffstat (limited to 'lib/puppet/network/http')
| -rw-r--r-- | lib/puppet/network/http/rack.rb | 19 | ||||
| -rw-r--r-- | lib/puppet/network/http/rack/xmlrpc.rb | 65 |
2 files changed, 83 insertions, 1 deletions
diff --git a/lib/puppet/network/http/rack.rb b/lib/puppet/network/http/rack.rb index 58f49416b..aa81b45f7 100644 --- a/lib/puppet/network/http/rack.rb +++ b/lib/puppet/network/http/rack.rb @@ -2,6 +2,7 @@ require 'rack' require 'puppet/network/http' require 'puppet/network/http/rack/rest' +require 'puppet/network/http/rack/xmlrpc' # An rack application, for running the Puppet HTTP Server. class Puppet::Network::HTTP::Rack @@ -14,6 +15,14 @@ class Puppet::Network::HTTP::Rack @rest_http_handler = Puppet::Network::HTTP::RackREST.new() protocols.delete :rest + # Prepare the XMLRPC handler, for backward compatibility (if requested) + if args[:protocols].include?(:xmlrpc) + raise ArgumentError, "XMLRPC was requested, but no handlers were given" if !args.include?(:xmlrpc_handlers) + + @xmlrpc_http_handler = Puppet::Network::HTTP::RackXMLRPC.new(args[:xmlrpc_handlers]) + protocols.delete :xmlrpc + end + raise ArgumentError, "there were unknown :protocols specified." if !protocols.empty? end @@ -27,8 +36,16 @@ class Puppet::Network::HTTP::Rack response = Rack::Response.new() Puppet.debug 'Handling request: %s %s' % [request.request_method, request.fullpath] + # if we shall serve XMLRPC, have /RPC2 go to the xmlrpc handler + if @xmlrpc_http_handler and request.path_info.start_with?('/RPC2') + handler = @xmlrpc_http_handler + else + # everything else is handled by the new REST handler + handler = @rest_http_handler + end + begin - @rest_http_handler.process(request, response) + handler.process(request, response) rescue => detail # Send a Status 500 Error on unhandled exceptions. response.status = 500 diff --git a/lib/puppet/network/http/rack/xmlrpc.rb b/lib/puppet/network/http/rack/xmlrpc.rb new file mode 100644 index 000000000..ef686cd4f --- /dev/null +++ b/lib/puppet/network/http/rack/xmlrpc.rb @@ -0,0 +1,65 @@ +require 'puppet/network/http/rack/httphandler' +require 'puppet/network/xmlrpc/server' +require 'resolv' + +class Puppet::Network::HTTP::RackXMLRPC < Puppet::Network::HTTP::RackHttpHandler + def initialize(handlers) + @xmlrpc_server = Puppet::Network::XMLRPCServer.new + handlers.each do |name| + Puppet.debug " -> register xmlrpc namespace %s" % name + unless handler = Puppet::Network::Handler.handler(name) + raise ArgumentError, "Invalid XMLRPC handler %s" % name + end + @xmlrpc_server.add_handler(handler.interface, handler.new({})) + end + super() + end + + def process(request, response) + # errors are sent as text/plain + response['Content-Type'] = 'text/plain' + if not request.post? then + response.status = 405 + response.write 'Method Not Allowed' + return + end + if request.media_type() != "text/xml" then + response.status = 400 + response.write 'Bad Request' + return + end + + # get auth/certificate data + client_request = build_client_request(request) + + response_body = @xmlrpc_server.process(request.body, client_request) + + response.status = 200 + response['Content-Type'] = 'text/xml; charset=utf-8' + response.write response_body + end + + def build_client_request(request) + ip = request.ip + + # if we find SSL info in the headers, use them to get a hostname. + # try this with :ssl_client_header, which defaults should work for + # Apache with StdEnvVars. + if dn = request.env[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/) + node = dn_matchdata[1].to_str + authenticated = (request.env[Puppet[:ssl_client_verify_header]] == 'SUCCESS') + else + begin + node = Resolv.getname(ip) + rescue => detail + Puppet.err "Could not resolve %s: %s" % [ip, detail] + node = "unknown" + end + authenticated = false + end + + Puppet::Network::ClientRequest.new(node, ip, authenticated) + end + +end + |
