summaryrefslogtreecommitdiffstats
path: root/lib/puppet/network
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/network')
-rw-r--r--lib/puppet/network/handler/master.rb24
-rw-r--r--lib/puppet/network/http/handler.rb55
-rw-r--r--lib/puppet/network/http/mongrel/rest.rb41
-rw-r--r--lib/puppet/network/http/webrick/rest.rb51
4 files changed, 97 insertions, 74 deletions
diff --git a/lib/puppet/network/handler/master.rb b/lib/puppet/network/handler/master.rb
index 851ccc7b2..a050b089b 100644
--- a/lib/puppet/network/handler/master.rb
+++ b/lib/puppet/network/handler/master.rb
@@ -56,7 +56,8 @@ class Puppet::Network::Handler
# Call our various handlers; this handler is getting deprecated.
def getconfig(facts, format = "marshal", client = nil, clientip = nil)
facts = decode_facts(facts)
- client, clientip = clientname(client, clientip, facts)
+
+ client ||= facts["hostname"]
# Pass the facts to the fact handler
Puppet::Node::Facts.new(client, facts).save unless local?
@@ -66,27 +67,6 @@ class Puppet::Network::Handler
return translate(catalog.extract)
end
- private
-
- # Manipulate the client name as appropriate.
- def clientname(name, ip, facts)
- # Always use the hostname from Facter.
- client = facts["hostname"]
- clientip = facts["ipaddress"]
- if Puppet[:node_name] == 'cert'
- if name
- client = name
- facts["fqdn"] = client
- facts["hostname"], facts["domain"] = client.split('.', 2)
- end
- if ip
- clientip = ip
- end
- end
-
- return client, clientip
- end
-
#
def decode_facts(facts)
if @local
diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb
index c05d4907f..3c14c8a40 100644
--- a/lib/puppet/network/http/handler.rb
+++ b/lib/puppet/network/http/handler.rb
@@ -1,30 +1,30 @@
module Puppet::Network::HTTP::Handler
-
+
def initialize_for_puppet(args = {})
raise ArgumentError unless @server = args[:server]
raise ArgumentError unless @handler = args[:handler]
@model = find_model_for_handler(@handler)
end
-
+
# handle an HTTP request
def process(request, response)
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)
+ 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
def model
@model
end
-
+
def do_find(request, response)
- key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]")
+ key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path(request)}]")
args = params(request)
result = model.find(key, args).to_yaml
encode_result(request, response, result)
@@ -37,7 +37,7 @@ module Puppet::Network::HTTP::Handler
end
def do_destroy(request, response)
- key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]")
+ key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path(request)}]")
args = params(request)
result = model.destroy(key, args)
encode_result(request, response, YAML.dump(result))
@@ -46,70 +46,73 @@ module Puppet::Network::HTTP::Handler
def do_save(request, response)
data = body(request).to_s
raise ArgumentError, "No data to save" if !data or data.empty?
- # args = params(request)
+ args = params(request)
obj = model.from_yaml(data)
- result = save_object(obj).to_yaml
+ result = save_object(obj, args).to_yaml
encode_result(request, response, result)
end
-
- def save_object(obj)
- obj.save
+
+ # LAK:NOTE This has to be here for testing; it's a stub-point so
+ # we keep infinite recursion from happening.
+ def save_object(object, args)
+ object.save(args)
end
-
+
def do_exception(request, response, exception, status=404)
encode_result(request, response, exception.to_yaml, status)
end
-
+
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 to be overridden by the including web server class
+
def register_handler
raise NotImplementedError
end
-
+
def http_method(request)
raise NotImplementedError
end
-
+
def path(request)
raise NotImplementedError
end
-
+
def request_key(request)
raise NotImplementedError
end
-
+
def body(request)
raise NotImplementedError
end
-
+
def params(request)
raise NotImplementedError
end
-
+
def encode_result(request, response, result, status = 200)
raise NotImplementedError
end
diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb
index a471a62bf..520ad67f0 100644
--- a/lib/puppet/network/http/mongrel/rest.rb
+++ b/lib/puppet/network/http/mongrel/rest.rb
@@ -3,45 +3,64 @@ require 'puppet/network/http/handler'
class Puppet::Network::HTTP::MongrelREST < Mongrel::HttpHandler
include Puppet::Network::HTTP::Handler
-
+
def initialize(args={})
super()
initialize_for_puppet(args)
end
+ # Return the query params for this request. We had to expose this method for
+ # testing purposes.
+ def params(request)
+ Mongrel::HttpRequest.query_parse(request.params["QUERY_STRING"]).merge(client_info(request))
+ end
+
private
-
+
# 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)
end
end
+
+ def client_info(request)
+ result = {}
+ params = request.params
+ result[:ip] = params["REMOTE_ADDR"]
+
+ # JJM #906 The following dn.match regular expression is forgiving
+ # enough to match the two Distinguished Name string contents
+ # coming from Apache, Pound or other reverse SSL proxies.
+ if dn = params[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
+ result[:node] = dn_matchdata[1].to_str
+ result[:authenticated] = (params[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
+ else
+ result[:authenticated] = false
+ end
+
+ return result
+ end
end
diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb
index b43912196..a235fb4f3 100644
--- a/lib/puppet/network/http/webrick/rest.rb
+++ b/lib/puppet/network/http/webrick/rest.rb
@@ -1,46 +1,67 @@
require 'puppet/network/http/handler'
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)
+ raise ArgumentError, "server is required" unless server
+ super(server)
+ initialize_for_puppet(:server => server, :handler => handler)
+ end
+
+ # We had to expose this method for testing purposes.
+ def params(request)
+ result = request.query
+ result.merge(client_information(request))
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 http_method(request)
request.request_method
end
-
+
def path(request)
# LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
x = '/' + request.path.split('/')[1]
end
-
+
def request_key(request)
# LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
x = request.path.split('/')[2]
end
-
+
def body(request)
request.body
end
-
- def params(request)
- request.query
- end
-
+
def encode_result(request, response, result, status = 200)
response.status = status
response.body = result
end
+
+ # Retrieve node/cert/ip information from the request object.
+ def client_information(request)
+ result = {}
+ if peer = request.peeraddr and ip = peer[3]
+ result[:ip] = ip
+ end
+
+ # If they have a certificate (which will almost always be true)
+ # then we get the hostname from the cert, instead of via IP
+ # info
+ result[:authenticated] = false
+ if cert = request.client_cert and nameary = cert.subject.to_a.find { |ary| ary[0] == "CN" }
+ result[:node] = nameary[1]
+ result[:authenticated] = true
+ end
+
+ result
+ end
end