File: http_pool_spec.rb

package info (click to toggle)
puppet 5.5.22-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 21,316 kB
  • sloc: ruby: 254,925; sh: 1,608; xml: 219; makefile: 153; sql: 103
file content (120 lines) | stat: -rw-r--r-- 3,653 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
require 'spec_helper'
require 'puppet_spec/https'
require 'puppet_spec/files'
require 'puppet/network/http_pool'

describe Puppet::Network::HttpPool do
  include PuppetSpec::Files

  before :all do
    WebMock.disable!
  end

  after :all do
    WebMock.enable!
  end

  before :each do
    # make sure we don't take too long
    Puppet[:http_connect_timeout] = '5s'
  end

  let(:hostname) { '127.0.0.1' }
  let(:wrong_hostname) { 'localhost' }
  let(:server) { PuppetSpec::HTTPSServer.new }

  context "when calling deprecated HttpPool methods" do
    let(:ssl_host) {
      # use server's cert/key as the client cert/key
      host = Puppet::SSL::Host.new
      host.key = Puppet::SSL::Key.from_instance(server.server_key, host.name)
      host.certificate = Puppet::SSL::Certificate.from_instance(server.server_cert, host.name)
      host
    }

    before(:each) do
      ssldir = tmpdir('http_pool')
      Puppet[:ssldir] = ssldir
      Puppet.settings.use(:main, :ssl)

      File.write(Puppet[:localcacert], server.ca_cert.to_pem)
      File.write(Puppet[:hostcrl], server.ca_crl.to_pem)
      File.write(Puppet[:hostcert], server.server_cert.to_pem)
      File.write(Puppet[:hostprivkey], server.server_key.to_pem)
    end

    # Can't use `around(:each)` because it will cause ssl_host to be
    # created outside of any rspec example, and $confdir won't be set
    before(:each) do
      Puppet.push_context(ssl_host: ssl_host)
    end

    after (:each) do
      Puppet.pop_context
    end

    def connection(host, port)
      Puppet::Network::HttpPool.http_instance(host, port, use_ssl: true)
    end

    shared_examples_for 'HTTPS client' do
      it "connects over SSL" do
        server.start_server do |port|
          http = connection(hostname, port)
          res = http.get('/')
          expect(res.code).to eq('200')
        end
      end

      it "raises if the server's cert doesn't match the hostname we connected to" do
        server.start_server do |port|
          http = connection(wrong_hostname, port)
          expect {
            http.get('/')
          }.to raise_error { |err|
            expect(err).to be_instance_of(Puppet::Error)
            expect(err.message).to match(/\AServer hostname '#{wrong_hostname}' did not match server certificate; expected one of (.+)/)

            md = err.message.match(/expected one of (.+)/)
            expect(md[1].split(', ')).to contain_exactly('127.0.0.1', 'DNS:127.0.0.1', 'DNS:127.0.0.2')
          }
        end
      end

      it "raises if the server's CA is unknown" do
        # File must exist and by not empty so DefaultValidator doesn't
        # downgrade to VERIFY_NONE, so use a different CA that didn't
        # issue the server's cert
        capath = tmpfile('empty')
        File.write(capath, PuppetSpec::HTTPSServer::UNKNOWN_CA)
        Puppet[:localcacert] = capath
        Puppet[:certificate_revocation] = false

        server.start_server do |port|
          http = connection(hostname, port)
          expect {
            http.get('/')
          }.to raise_error(Puppet::Error,
                           %r{certificate verify failed.* .self signed certificate in certificate chain for /CN=Test CA.})
        end
      end
    end


    context "when using single use HTTPS connections" do
      include_examples 'HTTPS client'
    end

    context "when using persistent HTTPS connections" do
      around :each do |example|
        pool = Puppet::Network::HTTP::Pool.new
        Puppet.override(:http_pool => pool) do
          example.run
        end
        pool.close
      end

      include_examples 'HTTPS client'
    end
  end
end