diff options
author | Luke Kanies <luke@madstop.com> | 2008-04-15 12:09:13 -0500 |
---|---|---|
committer | Luke Kanies <luke@madstop.com> | 2008-04-15 12:09:13 -0500 |
commit | d738f31dd33f6f4683b78f49041a302e4d95eae7 (patch) | |
tree | 3e73ac107caf7c82179a4eb1ecedbe0af2fc3c31 | |
parent | d834242db13a827a34340c5f2e51c8df532d5196 (diff) | |
download | puppet-d738f31dd33f6f4683b78f49041a302e4d95eae7.tar.gz puppet-d738f31dd33f6f4683b78f49041a302e4d95eae7.tar.xz puppet-d738f31dd33f6f4683b78f49041a302e4d95eae7.zip |
Adding the necessary tests for webrick to have logging and
ssl. The tests can't be completed until the certificate work
is all done.
-rw-r--r-- | lib/puppet/network/http/webrick.rb | 74 | ||||
-rw-r--r-- | spec/unit/network/http/webrick.rb | 145 |
2 files changed, 218 insertions, 1 deletions
diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index 3a37e2071..762c29451 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -22,7 +22,13 @@ class Puppet::Network::HTTP::WEBrick @protocols = args[:protocols] @handlers = args[:handlers] - @server = WEBrick::HTTPServer.new(:BindAddress => args[:address], :Port => args[:port]) + + arguments = {:BindAddress => args[:address], :Port => args[:port]} + arguments.merge!(setup_logger) + arguments.merge!(setup_ssl) + + @server = WEBrick::HTTPServer.new(arguments) + setup_handlers @mutex.synchronize do @@ -48,6 +54,72 @@ class Puppet::Network::HTTP::WEBrick end end + # Configure out http log file. + def setup_logger + # Make sure the settings are all ready for us. + Puppet.settings.use(:main, :ssl, Puppet[:name]) + + if Puppet[:name] == "puppetmasterd" + file = Puppet[:masterhttplog] + else + file = Puppet[:httplog] + end + + # open the log manually to prevent file descriptor leak + file_io = ::File.open(file, "a+") + file_io.sync + file_io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) + + args = [file_io] + args << WEBrick::Log::DEBUG if Puppet::Util::Log.level == :debug + + logger = WEBrick::Log.new(*args) + return :Logger => logger, :AccessLog => [ + [logger, WEBrick::AccessLog::COMMON_LOG_FORMAT ], + [logger, WEBrick::AccessLog::REFERER_LOG_FORMAT ] + ] + end + + # Add all of the ssl cert information. + def setup_ssl + results = {} + + results[:SSLCertificateStore] = setup_crl if Puppet[:cacrl] != 'false' + + results[:SSLCertificate] = self.cert + results[:SSLPrivateKey] = self.key + results[:SSLStartImmediately] = true + results[:SSLEnable] = true + results[:SSLCACertificateFile] = Puppet[:localcacert] + results[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_PEER + results[:SSLCertName] = nil + + results + end + + # Create our Certificate revocation list + def setup_crl + nil + if Puppet[:cacrl] == 'false' + # No CRL, no store needed + return nil + end + unless File.exist?(Puppet[:cacrl]) + raise Puppet::Error, "Could not find CRL; set 'cacrl' to 'false' to disable CRL usage" + end + crl = OpenSSL::X509::CRL.new(File.read(Puppet[:cacrl])) + store = OpenSSL::X509::Store.new + store.purpose = OpenSSL::X509::PURPOSE_ANY + store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK + unless self.ca_cert + raise Puppet::Error, "Could not find CA certificate" + end + + store.add_file(Puppet[:localcacert]) + store.add_crl(crl) + return store + end + private def setup_handlers diff --git a/spec/unit/network/http/webrick.rb b/spec/unit/network/http/webrick.rb index 05ed2f0e2..150e9efbc 100644 --- a/spec/unit/network/http/webrick.rb +++ b/spec/unit/network/http/webrick.rb @@ -18,6 +18,7 @@ describe Puppet::Network::HTTP::WEBrick, "when turning on listening" do [:mount, :start, :shutdown].each {|meth| @mock_webrick.stubs(meth)} WEBrick::HTTPServer.stubs(:new).returns(@mock_webrick) @server = Puppet::Network::HTTP::WEBrick.new + [:setup_logger, :setup_ssl].each {|meth| @server.stubs(meth).returns({})} # the empty hash is required because of how we're merging @listen_params = { :address => "127.0.0.1", :port => 31337, :handlers => [ :node, :catalog ], :protocols => [ :rest ] } end @@ -53,6 +54,26 @@ describe Puppet::Network::HTTP::WEBrick, "when turning on listening" do }.returns(@mock_webrick) @server.listen(@listen_params) end + + it "should configure a logger for webrick" do + @server.expects(:setup_logger).returns(:Logger => :mylogger) + + WEBrick::HTTPServer.expects(:new).with {|args| + args[:Logger] == :mylogger + }.returns(@mock_webrick) + + @server.listen(@listen_params) + end + + it "should configure SSL for webrick" do + @server.expects(:setup_ssl).returns(:Ssl => :testing, :Other => :yay) + + WEBrick::HTTPServer.expects(:new).with {|args| + args[:Ssl] == :testing and args[:Other] == :yay + }.returns(@mock_webrick) + + @server.listen(@listen_params) + end it "should be listening" do @server.listen(@listen_params) @@ -105,6 +126,7 @@ describe Puppet::Network::HTTP::WEBrick, "when turning off listening" do [:mount, :start, :shutdown].each {|meth| @mock_webrick.stubs(meth)} WEBrick::HTTPServer.stubs(:new).returns(@mock_webrick) @server = Puppet::Network::HTTP::WEBrick.new + [:setup_logger, :setup_ssl].each {|meth| @server.stubs(meth).returns({})} # the empty hash is required because of how we're merging @listen_params = { :address => "127.0.0.1", :port => 31337, :handlers => [ :node, :catalog ], :protocols => [ :rest ] } end @@ -124,3 +146,126 @@ describe Puppet::Network::HTTP::WEBrick, "when turning off listening" do @server.should_not be_listening end end + +describe Puppet::Network::HTTP::WEBrick do + before do + @mock_webrick = stub('webrick', :[] => {}) + [:mount, :start, :shutdown].each {|meth| @mock_webrick.stubs(meth)} + WEBrick::HTTPServer.stubs(:new).returns(@mock_webrick) + @server = Puppet::Network::HTTP::WEBrick.new + end + + describe "when configuring an x509 store" do + it "should add the CRL to the store" + + it "should create a new x509 store" + + it "should add the CA certificate to the store" + + it "should set the store's flags to 'OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK'" + + it "should set the store's purpose to 'OpenSSL::X509::PURPOSE_ANY'" + + it "should return the store" + end + + describe "when configuring an http logger" do + before do + Puppet.settings.stubs(:value).returns "something" + Puppet.settings.stubs(:use) + @filehandle = stub 'handle', :fcntl => nil, :sync => nil + + File.stubs(:open).returns @filehandle + end + + it "should use the settings for :main, :ssl, and the process name" do + Puppet.settings.stubs(:value).with(:name).returns "myname" + Puppet.settings.expects(:use).with(:main, :ssl, "myname") + + @server.setup_logger + end + + it "should use the masterlog if the process name is 'puppetmasterd'" do + Puppet.settings.stubs(:value).with(:name).returns "puppetmasterd" + Puppet.settings.expects(:value).with(:masterhttplog).returns "/master/log" + + File.expects(:open).with("/master/log", "a+").returns @filehandle + + @server.setup_logger + end + + it "should use the httplog if the process name is not 'puppetmasterd'" do + Puppet.settings.stubs(:value).with(:name).returns "other" + Puppet.settings.expects(:value).with(:httplog).returns "/other/log" + + File.expects(:open).with("/other/log", "a+").returns @filehandle + + @server.setup_logger + end + + describe "and creating the logging filehandle" do + it "should set fcntl to 'Fcntl::F_SETFD, Fcntl::FD_CLOEXEC'" do + @filehandle.expects(:fcntl).with(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) + + @server.setup_logger + end + + it "should sync the filehandle" do + @filehandle.expects(:sync) + + @server.setup_logger + end + end + + it "should create a new WEBrick::Log instance with the open filehandle" do + WEBrick::Log.expects(:new).with(@filehandle) + + @server.setup_logger + end + + it "should set debugging if the current loglevel is :debug" do + Puppet::Util::Log.expects(:level).returns :debug + + WEBrick::Log.expects(:new).with { |handle, debug| debug == WEBrick::Log::DEBUG } + + @server.setup_logger + end + + it "should return the logger as the main log" do + logger = mock 'logger' + WEBrick::Log.expects(:new).returns logger + + @server.setup_logger[:Logger].should == logger + end + + it "should return the logger as the access log using both the Common and Referer log format" do + logger = mock 'logger' + WEBrick::Log.expects(:new).returns logger + + @server.setup_logger[:AccessLog].should == [ + [logger, WEBrick::AccessLog::COMMON_LOG_FORMAT], + [logger, WEBrick::AccessLog::REFERER_LOG_FORMAT] + ] + end + end + + describe "when configuring ssl" do + it "should add an x509 store if the CRL is enabled" + + it "should not add an x509 store if the CRL is disabled" + + it "should configure the certificate" + + it "should configure the private key" + + it "should start ssl immediately" + + it "should enable ssl" + + it "should specify the path to the CA certificate" + + it "should configure the verification method as 'OpenSSL::SSL::VERIFY_PEER'" + + it "should set the certificate name to 'nil'" + end +end |