require 'spec_helper' require 'puppet/network/http_pool' class Puppet::Network::HttpPool::FooClient def initialize(host, port, options = {}) @host = host @port = port end attr_reader :host, :port end describe Puppet::Network::HttpPool do include PuppetSpec::Files describe "when registering an http client class" do let(:http_impl) { Puppet::Network::HttpPool::FooClient } around :each do |example| orig_class = Puppet::Network::HttpPool.http_client_class begin example.run ensure Puppet::Network::HttpPool.http_client_class = orig_class end end it "returns instances of the http client class" do Puppet::Network::HttpPool.http_client_class = http_impl http = Puppet::Network::HttpPool.http_instance("me", 54321) expect(http).to be_an_instance_of(http_impl) expect(http.host).to eq('me') expect(http.port).to eq(54321) end it "uses the default http client" do expect(Puppet.runtime[:http]).to be_an_instance_of(Puppet::HTTP::Client) end it "switches to the external client implementation" do Puppet::Network::HttpPool.http_client_class = http_impl expect(Puppet.runtime[:http]).to be_an_instance_of(Puppet::HTTP::ExternalClient) end it "always uses an explicitly registered http implementation" do Puppet::Network::HttpPool.http_client_class = http_impl new_impl = double('new_http_impl') Puppet.initialize_settings([], true, true, http: new_impl) expect(Puppet.runtime[:http]).to eq(new_impl) end end describe "when managing http instances" do it "should return an http instance created with the passed host and port" do http = Puppet::Network::HttpPool.http_instance("me", 54321) expect(http).to be_a_kind_of Puppet::Network::HTTP::Connection expect(http.address).to eq('me') expect(http.port).to eq(54321) end it "should enable ssl on the http instance by default" do expect(Puppet::Network::HttpPool.http_instance("me", 54321)).to be_use_ssl end it "can set ssl using an option" do expect(Puppet::Network::HttpPool.http_instance("me", 54321, false)).not_to be_use_ssl expect(Puppet::Network::HttpPool.http_instance("me", 54321, true)).to be_use_ssl end it 'has an http_ssl_instance method' do expect(Puppet::Network::HttpPool.http_ssl_instance("me", 54321)).to be_use_ssl end context "when calling 'connection'" do it 'requires an ssl_context' do expect { Puppet::Network::HttpPool.connection('me', 8140) }.to raise_error(ArgumentError, "An ssl_context is required when connecting to 'https://me:8140'") end it 'creates a verifier from the context' do ssl_context = Puppet::SSL::SSLContext.new expect( Puppet::Network::HttpPool.connection('me', 8140, ssl_context: ssl_context).verifier ).to be_a_kind_of(Puppet::SSL::Verifier) end it 'does not use SSL when specified' do expect(Puppet::Network::HttpPool.connection('me', 8140, use_ssl: false)).to_not be_use_ssl end it 'defaults to SSL' do ssl_context = Puppet::SSL::SSLContext.new conn = Puppet::Network::HttpPool.connection('me', 8140, ssl_context: ssl_context) expect(conn).to be_use_ssl end it 'warns if an ssl_context is used for an http connection' do expect(Puppet).to receive(:warning).with("An ssl_context is unnecessary when connecting to 'http://me:8140' and will be ignored") ssl_context = Puppet::SSL::SSLContext.new Puppet::Network::HttpPool.connection('me', 8140, use_ssl: false, ssl_context: ssl_context) end end describe 'peer verification' do before(:each) do Puppet[:ssldir] = tmpdir('ssl') Puppet.settings.use(:main) Puppet[:certname] = 'signed' File.write(Puppet[:localcacert], cert_fixture('ca.pem')) File.write(Puppet[:hostcrl], crl_fixture('crl.pem')) File.write(Puppet[:hostcert], cert_fixture('signed.pem')) File.write(Puppet[:hostprivkey], key_fixture('signed-key.pem')) end it 'enables peer verification by default' do stub_request(:get, "https://me:54321") conn = Puppet::Network::HttpPool.http_instance("me", 54321, true) expect_any_instance_of(Net::HTTP).to receive(:start) do |http| expect(http.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER) end conn.get('/') end it 'can disable peer verification' do stub_request(:get, "https://me:54321") conn = Puppet::Network::HttpPool.http_instance("me", 54321, true, false) expect_any_instance_of(Net::HTTP).to receive(:start) do |http| expect(http.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE) end conn.get('/') end end it "should not cache http instances" do expect(Puppet::Network::HttpPool.http_instance("me", 54321)). not_to equal(Puppet::Network::HttpPool.http_instance("me", 54321)) end end end