puppet 6.4.1-x86-mingw32 → 6.4.2-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -5
- data/lib/puppet/application.rb +2 -2
- data/lib/puppet/provider/package/gem.rb +51 -27
- data/lib/puppet/provider/package/yum.rb +1 -0
- data/lib/puppet/provider/user/directoryservice.rb +16 -4
- data/lib/puppet/ssl/host.rb +0 -12
- data/lib/puppet/ssl/validator/default_validator.rb +21 -0
- data/lib/puppet/ssl/verifier_adapter.rb +2 -0
- data/lib/puppet/type/schedule.rb +4 -0
- data/lib/puppet/version.rb +1 -1
- data/man/man5/puppet.conf.5 +1 -1
- data/man/man8/puppet.8 +1 -1
- data/spec/integration/network/http_pool_spec.rb +0 -2
- data/spec/unit/application_spec.rb +0 -9
- data/spec/unit/provider/package/gem_spec.rb +55 -39
- data/spec/unit/provider/package/puppet_gem_spec.rb +21 -33
- data/spec/unit/provider/package/yum_spec.rb +34 -0
- data/spec/unit/provider/user/directoryservice_spec.rb +39 -2
- data/spec/unit/ssl/validator_spec.rb +2 -0
- metadata +2 -7
- data/lib/puppet/rest/client.rb +0 -87
- data/spec/integration/rest/client_spec.rb +0 -73
- data/spec/unit/rest/client_spec.rb +0 -164
@@ -15,70 +15,58 @@ describe Puppet::Type.type(:package).provider(:puppet_gem) do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
if Puppet::Util::Platform.windows?
|
18
|
-
let(:
|
18
|
+
let(:provider_gem_cmd) { 'gem' }
|
19
19
|
else
|
20
|
-
let(:
|
20
|
+
let(:provider_gem_cmd) { '/opt/puppetlabs/puppet/bin/gem' }
|
21
21
|
end
|
22
22
|
|
23
|
+
let(:execute_options) { {:failonfail => true, :combine => true, :custom_environment => {"HOME"=>ENV["HOME"]}} }
|
24
|
+
|
23
25
|
before :each do
|
24
26
|
resource.provider = provider
|
27
|
+
allow(described_class).to receive(:command).with(:gemcmd).and_return(provider_gem_cmd)
|
25
28
|
end
|
26
29
|
|
27
30
|
context "when installing" do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
before :each do
|
32
|
+
allow(provider).to receive(:rubygem_version).and_return('1.9.9')
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should use the path to the gem command" do
|
36
|
+
allow(described_class).to receive(:which).with(provider_gem_cmd).and_return(provider_gem_cmd)
|
37
|
+
expect(described_class).to receive(:execute).with(be_a(Array), execute_options) { |args| expect(args[0]).to eq(provider_gem_cmd) }.and_return('')
|
34
38
|
provider.install
|
35
39
|
end
|
36
40
|
|
37
41
|
it "should not append install_options by default" do
|
38
|
-
expect(
|
39
|
-
expect(args.length).to eq(5)
|
40
|
-
''
|
41
|
-
end
|
42
|
+
expect(described_class).to receive(:execute_gem_command).with(%w{install --no-rdoc --no-ri myresource}).and_return('')
|
42
43
|
provider.install
|
43
44
|
end
|
44
45
|
|
45
46
|
it "should allow setting an install_options parameter" do
|
46
47
|
resource[:install_options] = [ '--force', {'--bindir' => '/usr/bin' } ]
|
47
|
-
expect(
|
48
|
-
expect(args[2]).to eq('--force')
|
49
|
-
expect(args[3]).to eq('--bindir=/usr/bin')
|
50
|
-
''
|
51
|
-
end
|
48
|
+
expect(described_class).to receive(:execute_gem_command).with(%w{install --force --bindir=/usr/bin --no-rdoc --no-ri myresource}).and_return('')
|
52
49
|
provider.install
|
53
50
|
end
|
54
51
|
end
|
55
52
|
|
56
53
|
context "when uninstalling" do
|
57
|
-
it "should use the path to the gem" do
|
58
|
-
|
59
|
-
expect(
|
60
|
-
|
61
|
-
''
|
62
|
-
end
|
63
|
-
provider.install
|
54
|
+
it "should use the path to the gem command" do
|
55
|
+
allow(described_class).to receive(:which).with(provider_gem_cmd).and_return(provider_gem_cmd)
|
56
|
+
expect(described_class).to receive(:execute).with(be_a(Array), execute_options) { |args| expect(args[0]).to eq(provider_gem_cmd) }.and_return('')
|
57
|
+
provider.uninstall
|
64
58
|
end
|
65
59
|
|
66
60
|
it "should not append uninstall_options by default" do
|
67
|
-
expect(
|
68
|
-
expect(args.length).to eq(5)
|
69
|
-
''
|
70
|
-
end
|
61
|
+
expect(described_class).to receive(:execute_gem_command).with(%w{uninstall --executables --all myresource}).and_return('')
|
71
62
|
provider.uninstall
|
72
63
|
end
|
73
64
|
|
74
65
|
it "should allow setting an uninstall_options parameter" do
|
75
66
|
resource[:uninstall_options] = [ '--force', {'--bindir' => '/usr/bin' } ]
|
76
|
-
expect(
|
77
|
-
expect(args[5]).to eq('--force')
|
78
|
-
expect(args[6]).to eq('--bindir=/usr/bin')
|
79
|
-
''
|
80
|
-
end
|
67
|
+
expect(described_class).to receive(:execute_gem_command).with(%w{uninstall --executables --all myresource --force --bindir=/usr/bin}).and_return('')
|
81
68
|
provider.uninstall
|
82
69
|
end
|
83
70
|
end
|
71
|
+
|
84
72
|
end
|
@@ -12,6 +12,40 @@ describe Puppet::Type.type(:package).provider(:yum) do
|
|
12
12
|
expect(described_class.specificity).to be < 200
|
13
13
|
end
|
14
14
|
|
15
|
+
describe "should have logical defaults" do
|
16
|
+
[2, 2018].each do |ver|
|
17
|
+
it "should be the default provider on Amazon Linux #{ver}" do
|
18
|
+
allow(Facter).to receive(:value).with(:operatingsystem).and_return('amazon')
|
19
|
+
allow(Facter).to receive(:value).with(:osfamily).and_return('redhat')
|
20
|
+
allow(Facter).to receive(:value).with(:operatingsystemmajrelease).and_return(ver)
|
21
|
+
expect(described_class).to be_default
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Array(4..7).each do |ver|
|
26
|
+
it "should be default for redhat #{ver}" do
|
27
|
+
allow(Facter).to receive(:value).with(:operatingsystem).and_return('redhat')
|
28
|
+
allow(Facter).to receive(:value).with(:osfamily).and_return('redhat')
|
29
|
+
allow(Facter).to receive(:value).with(:operatingsystemmajrelease).and_return(ver.to_s)
|
30
|
+
expect(described_class).to be_default
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not be default for redhat 8" do
|
35
|
+
allow(Facter).to receive(:value).with(:operatingsystem).and_return('redhat')
|
36
|
+
allow(Facter).to receive(:value).with(:osfamily).and_return('redhat')
|
37
|
+
allow(Facter).to receive(:value).with(:operatingsystemmajrelease).and_return('8')
|
38
|
+
expect(described_class).not_to be_default
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should not be default for Ubuntu 16.04" do
|
42
|
+
allow(Facter).to receive(:value).with(:operatingsystem).and_return('ubuntu')
|
43
|
+
allow(Facter).to receive(:value).with(:osfamily).and_return('ubuntu')
|
44
|
+
allow(Facter).to receive(:value).with(:operatingsystemmajrelease).and_return('16.04')
|
45
|
+
expect(described_class).not_to be_default
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
15
49
|
describe "when supplied the source param" do
|
16
50
|
let(:name) { 'baz' }
|
17
51
|
|
@@ -294,7 +294,7 @@ describe Puppet::Type.type(:user).provider(:directoryservice) do
|
|
294
294
|
before :each do
|
295
295
|
# Stub out all calls to dscl with default values from above
|
296
296
|
defaults.each do |key, val|
|
297
|
-
allow(provider).to receive(:
|
297
|
+
allow(provider).to receive(:create_attribute_with_dscl).with('Users', username, key, val)
|
298
298
|
end
|
299
299
|
|
300
300
|
# Mock the rest of the dscl calls. We can't assume that our Linux
|
@@ -327,11 +327,41 @@ describe Puppet::Type.type(:user).provider(:directoryservice) do
|
|
327
327
|
it 'should convert group names into integers' do
|
328
328
|
resource[:gid] = 'somegroup'
|
329
329
|
expect(Puppet::Util).to receive(:gid).with('somegroup').and_return(21)
|
330
|
-
expect(provider).to receive(:
|
330
|
+
expect(provider).to receive(:create_attribute_with_dscl).with('Users', username, 'PrimaryGroupID', 21)
|
331
331
|
provider.create
|
332
332
|
end
|
333
333
|
end
|
334
334
|
|
335
|
+
describe 'Update existing user' do
|
336
|
+
describe 'home=' do
|
337
|
+
context 'on OS X 10.14' do
|
338
|
+
before do
|
339
|
+
provider.instance_variable_set(:@property_hash, { home: 'value' })
|
340
|
+
allow(provider.class).to receive(:get_os_version).and_return('10.14')
|
341
|
+
end
|
342
|
+
|
343
|
+
it 'raises error' do
|
344
|
+
expect { provider.home = 'new' }.to \
|
345
|
+
raise_error(Puppet::Error, "OS X version 10.14 does not allow changing home using puppet")
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
describe 'uid=' do
|
351
|
+
context 'on OS X 10.14' do
|
352
|
+
before do
|
353
|
+
provider.instance_variable_set(:@property_hash, { uid: 'value' })
|
354
|
+
allow(provider.class).to receive(:get_os_version).and_return('10.14')
|
355
|
+
end
|
356
|
+
|
357
|
+
it 'raises error' do
|
358
|
+
expect { provider.uid = 'new' }.to \
|
359
|
+
raise_error(Puppet::Error, "OS X version 10.14 does not allow changing uid using puppet")
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
335
365
|
describe 'self#instances' do
|
336
366
|
it 'should create an array of provider instances' do
|
337
367
|
expect(provider.class).to receive(:get_all_users).and_return(['foo', 'bar'])
|
@@ -988,6 +1018,13 @@ describe Puppet::Type.type(:user).provider(:directoryservice) do
|
|
988
1018
|
end
|
989
1019
|
end
|
990
1020
|
|
1021
|
+
describe '#create_attribute_with_dscl' do
|
1022
|
+
it 'should raise an error if a dscl command raises an error' do
|
1023
|
+
expect(provider).to receive(:dscl).with('.', '-create', user_path, 'GeneratedUID', 'GUID').and_raise(Puppet::ExecutionFailure, 'boom')
|
1024
|
+
expect { provider.create_attribute_with_dscl('Users', username, 'GeneratedUID', 'GUID') }.to raise_error Puppet::Error, /Could not set the dscl GeneratedUID key with value: GUID/
|
1025
|
+
end
|
1026
|
+
end
|
1027
|
+
|
991
1028
|
describe '#get_users_plist' do
|
992
1029
|
let(:test_hash) do
|
993
1030
|
{
|
@@ -185,6 +185,7 @@ describe Puppet::SSL::Validator::DefaultValidator, unless: Puppet::Util::Platfor
|
|
185
185
|
allow(subject).to receive(:ssl_certificates_are_present?).and_return(true)
|
186
186
|
connection = double('Net::HTTP')
|
187
187
|
|
188
|
+
allow(connection).to receive(:address).and_return('puppet.com')
|
188
189
|
expect(connection).to receive(:cert_store=).with(ssl_host.ssl_store)
|
189
190
|
expect(connection).to receive(:ca_file=).with(ca_path)
|
190
191
|
expect(connection).to receive(:cert=).with(ssl_host.certificate.content)
|
@@ -200,6 +201,7 @@ describe Puppet::SSL::Validator::DefaultValidator, unless: Puppet::Util::Platfor
|
|
200
201
|
allow(subject).to receive(:ssl_certificates_are_present?).and_return(false)
|
201
202
|
connection = double('Net::HTTP')
|
202
203
|
|
204
|
+
allow(connection).to receive(:address).and_return('puppet.com')
|
203
205
|
expect(connection).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
204
206
|
|
205
207
|
subject.setup_connection(connection, ssl_host)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.4.
|
4
|
+
version: 6.4.2
|
5
5
|
platform: x86-mingw32
|
6
6
|
authors:
|
7
7
|
- Puppet Labs
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-04-
|
11
|
+
date: 2019-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: facter
|
@@ -1163,7 +1163,6 @@ files:
|
|
1163
1163
|
- lib/puppet/resource/status.rb
|
1164
1164
|
- lib/puppet/resource/type.rb
|
1165
1165
|
- lib/puppet/resource/type_collection.rb
|
1166
|
-
- lib/puppet/rest/client.rb
|
1167
1166
|
- lib/puppet/rest/errors.rb
|
1168
1167
|
- lib/puppet/rest/response.rb
|
1169
1168
|
- lib/puppet/rest/route.rb
|
@@ -1869,7 +1868,6 @@ files:
|
|
1869
1868
|
- spec/integration/reports_spec.rb
|
1870
1869
|
- spec/integration/resource/catalog_spec.rb
|
1871
1870
|
- spec/integration/resource/type_collection_spec.rb
|
1872
|
-
- spec/integration/rest/client_spec.rb
|
1873
1871
|
- spec/integration/ssl/certificate_request_spec.rb
|
1874
1872
|
- spec/integration/ssl/host_spec.rb
|
1875
1873
|
- spec/integration/ssl/key_spec.rb
|
@@ -2480,7 +2478,6 @@ files:
|
|
2480
2478
|
- spec/unit/resource/type_collection_spec.rb
|
2481
2479
|
- spec/unit/resource/type_spec.rb
|
2482
2480
|
- spec/unit/resource_spec.rb
|
2483
|
-
- spec/unit/rest/client_spec.rb
|
2484
2481
|
- spec/unit/rest/route_spec.rb
|
2485
2482
|
- spec/unit/scheduler/job_spec.rb
|
2486
2483
|
- spec/unit/scheduler/scheduler_spec.rb
|
@@ -3107,7 +3104,6 @@ test_files:
|
|
3107
3104
|
- spec/integration/reports_spec.rb
|
3108
3105
|
- spec/integration/resource/catalog_spec.rb
|
3109
3106
|
- spec/integration/resource/type_collection_spec.rb
|
3110
|
-
- spec/integration/rest/client_spec.rb
|
3111
3107
|
- spec/integration/ssl/certificate_request_spec.rb
|
3112
3108
|
- spec/integration/ssl/host_spec.rb
|
3113
3109
|
- spec/integration/ssl/key_spec.rb
|
@@ -3718,7 +3714,6 @@ test_files:
|
|
3718
3714
|
- spec/unit/resource/type_collection_spec.rb
|
3719
3715
|
- spec/unit/resource/type_spec.rb
|
3720
3716
|
- spec/unit/resource_spec.rb
|
3721
|
-
- spec/unit/rest/client_spec.rb
|
3722
3717
|
- spec/unit/rest/route_spec.rb
|
3723
3718
|
- spec/unit/scheduler/job_spec.rb
|
3724
3719
|
- spec/unit/scheduler/scheduler_spec.rb
|
data/lib/puppet/rest/client.rb
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
require 'httpclient'
|
2
|
-
|
3
|
-
require 'puppet'
|
4
|
-
require 'puppet/rest/response'
|
5
|
-
require 'puppet/rest/errors'
|
6
|
-
require 'puppet/util/ssl'
|
7
|
-
|
8
|
-
module Puppet::Rest
|
9
|
-
class Client
|
10
|
-
attr_reader :dns_resolver
|
11
|
-
|
12
|
-
# Create a new HTTP client for querying the given API.
|
13
|
-
# @param [Puppet::SSL::SSLContext] ssl_context the SSL configuration for this client
|
14
|
-
# @param [Integer] receive_timeout how long in seconds this client will wait
|
15
|
-
# for a response after making a request
|
16
|
-
# @param [HTTPClient] client the third-party HTTP client wrapped by this
|
17
|
-
# class. This param is only used for testing.
|
18
|
-
def initialize(ssl_context:,
|
19
|
-
receive_timeout: Puppet[:http_read_timeout],
|
20
|
-
client: HTTPClient.new(agent_name: nil,
|
21
|
-
default_header: {
|
22
|
-
'User-Agent' => Puppet[:http_user_agent],
|
23
|
-
'X-PUPPET-VERSION' => Puppet::PUPPETVERSION
|
24
|
-
}))
|
25
|
-
@client = client
|
26
|
-
@client.tcp_keepalive = true
|
27
|
-
@client.connect_timeout = Puppet[:http_connect_timeout]
|
28
|
-
@client.receive_timeout = receive_timeout
|
29
|
-
@client.transparent_gzip_decompression = true
|
30
|
-
|
31
|
-
if Puppet[:http_debug]
|
32
|
-
@client.debug_dev = $stderr
|
33
|
-
end
|
34
|
-
|
35
|
-
@ca_path = Puppet[:ssl_client_ca_auth] || Puppet[:localcacert]
|
36
|
-
@verifier = Puppet::SSL::Validator::DefaultValidator.new(@ca_path)
|
37
|
-
configure_verify_mode(ssl_context)
|
38
|
-
|
39
|
-
@dns_resolver = Puppet::Network::Resolver.new
|
40
|
-
end
|
41
|
-
|
42
|
-
# Make a GET request to the specified URL with the specified params.
|
43
|
-
# @param [URI::HTTPS] url the full path to query
|
44
|
-
# @param [Hash] query any URL params to add to send to the endpoint
|
45
|
-
# @param [Hash] header any additional entries to add to the default header
|
46
|
-
# @yields [String] chunks of the response body
|
47
|
-
# @raise [Puppet::Rest::ResponseError] if the response status is not OK
|
48
|
-
def get(url, query: nil, header: nil, &block)
|
49
|
-
begin
|
50
|
-
@client.get_content(url.to_s, { query: query, header: header }) do |chunk|
|
51
|
-
block.call(chunk)
|
52
|
-
end
|
53
|
-
rescue HTTPClient::BadResponseError => e
|
54
|
-
raise Puppet::Rest::ResponseError.new(e.message, Puppet::Rest::Response.new(e.res))
|
55
|
-
rescue OpenSSL::OpenSSLError => e
|
56
|
-
Puppet::Util::SSL.handle_connection_error(e, @verifier, url.host)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# Make a PUT request to the specified URL with the specified params.
|
61
|
-
# @param [URI::HTTPS] url the full path to query
|
62
|
-
# @param [String/Hash] body the contents of the PUT request
|
63
|
-
# @param [Hash] query any URL params to add to send to the endpoint
|
64
|
-
# @param [Hash] header any additional entries to add to the default header
|
65
|
-
# @return [Puppet::Rest::Response]
|
66
|
-
def put(url, body:, query: nil, header: nil)
|
67
|
-
begin
|
68
|
-
response = @client.put(url.to_s, body: body, query: query, header: header)
|
69
|
-
Puppet::Rest::Response.new(response)
|
70
|
-
rescue OpenSSL::OpenSSLError => e
|
71
|
-
Puppet::Util::SSL.handle_connection_error(e, @verifier, url.host)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
private
|
76
|
-
|
77
|
-
def configure_verify_mode(ssl_context)
|
78
|
-
@client.ssl_config.verify_callback = @verifier
|
79
|
-
@client.ssl_config.cert_store = ssl_context[:store]
|
80
|
-
@client.ssl_config.verify_mode = if !ssl_context[:verify_peer]
|
81
|
-
OpenSSL::SSL::VERIFY_NONE
|
82
|
-
else
|
83
|
-
OpenSSL::SSL::VERIFY_PEER
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'puppet_spec/https'
|
3
|
-
require 'puppet_spec/files'
|
4
|
-
require 'puppet/rest/client'
|
5
|
-
|
6
|
-
describe Puppet::Rest::Client, unless: Puppet::Util::Platform.jruby? do
|
7
|
-
include PuppetSpec::Files
|
8
|
-
|
9
|
-
before :all do
|
10
|
-
WebMock.disable!
|
11
|
-
end
|
12
|
-
|
13
|
-
after :all do
|
14
|
-
WebMock.enable!
|
15
|
-
end
|
16
|
-
|
17
|
-
let(:hostname) { '127.0.0.1' }
|
18
|
-
let(:wrong_hostname) { 'localhost' }
|
19
|
-
let(:server) { PuppetSpec::HTTPSServer.new }
|
20
|
-
let(:ssl) { Puppet::SSL::SSLProvider.new }
|
21
|
-
let(:ssl_context) { ssl.create_root_context(cacerts: [server.ca_cert], crls: [server.ca_crl]) }
|
22
|
-
let(:client) { Puppet::Rest::Client.new(ssl_context: ssl_context) }
|
23
|
-
|
24
|
-
before(:each) do
|
25
|
-
localcacert = tmpfile('rest_client')
|
26
|
-
File.write(localcacert, server.ca_cert.to_pem)
|
27
|
-
Puppet[:ssl_client_ca_auth] = localcacert
|
28
|
-
|
29
|
-
# make sure we don't take too long
|
30
|
-
Puppet[:http_connect_timeout] = '5s'
|
31
|
-
end
|
32
|
-
|
33
|
-
it "connects over SSL" do
|
34
|
-
server.start_server do |port|
|
35
|
-
uri = URI.parse("https://#{hostname}:#{port}/blah")
|
36
|
-
expect { |b|
|
37
|
-
client.get(uri, &b)
|
38
|
-
}.to yield_with_args('OK')
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'provides a meaningful error message when cert validation fails' do
|
43
|
-
ssl_context = ssl.create_root_context(
|
44
|
-
cacerts: [cert_fixture('netlock-arany-utf8.pem')]
|
45
|
-
)
|
46
|
-
client = Puppet::Rest::Client.new(ssl_context: ssl_context)
|
47
|
-
|
48
|
-
server.start_server do |port|
|
49
|
-
uri = URI.parse("https://#{hostname}:#{port}/blah")
|
50
|
-
expect {
|
51
|
-
client.get(uri)
|
52
|
-
}.to raise_error(Puppet::Error,
|
53
|
-
%r{certificate verify failed.* .self signed certificate in certificate chain for CN=Test CA.})
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'provides valuable error message when cert names do not match' do
|
58
|
-
server.start_server do |port|
|
59
|
-
uri = URI.parse("https://#{wrong_hostname}:#{port}/blah")
|
60
|
-
expect {
|
61
|
-
client.get(uri)
|
62
|
-
}.to raise_error do |error|
|
63
|
-
pending("PUP-8213") if RUBY_VERSION.to_f >= 2.4 && !Puppet::Util::Platform.jruby?
|
64
|
-
|
65
|
-
expect(error).to be_instance_of(Puppet::SSL::CertMismatchError)
|
66
|
-
expect(error.message).to match(/\AServer hostname '#{wrong_hostname}' did not match server certificate; expected one of (.+)/)
|
67
|
-
|
68
|
-
md = error.message.match(/expected one of (.+)/)
|
69
|
-
expect(md[1].split(', ')).to contain_exactly('127.0.0.1', 'DNS:127.0.0.1', 'DNS:127.0.0.2')
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,164 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'puppet/rest/client'
|
4
|
-
require 'puppet_spec/validators'
|
5
|
-
require 'puppet_spec/ssl'
|
6
|
-
|
7
|
-
describe Puppet::Rest::Client do
|
8
|
-
# Follows closely with spec/unit/network/http/connection_spec's
|
9
|
-
# 'ssl verifier' shared context
|
10
|
-
shared_examples 'connection error handling' do
|
11
|
-
let(:uri) { URI.parse('https://foo.com/blah') }
|
12
|
-
|
13
|
-
it 'provides a meaningful error message when cert validation fails' do
|
14
|
-
client.instance_variable_set(:@verifier,
|
15
|
-
ConstantErrorValidator.new(
|
16
|
-
error_string: 'foo'))
|
17
|
-
|
18
|
-
expect(http).to receive(:get_content).with(uri.to_s, query: nil, header: nil)
|
19
|
-
.and_raise(OpenSSL::OpenSSLError.new('certificate verify failed'))
|
20
|
-
expect{ client.get(uri) }.to raise_error do |error|
|
21
|
-
expect(error).to be_a(Puppet::Error)
|
22
|
-
expect(error.message).to include('foo')
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'provides valuable error message when cert names do not match' do
|
27
|
-
cert = PuppetSpec::SSL.self_signed_ca(PuppetSpec::SSL.create_private_key,
|
28
|
-
'/CN=bar.com')
|
29
|
-
client.instance_variable_set(:@verifier,
|
30
|
-
ConstantErrorValidator.new(
|
31
|
-
peer_certs: [cert]))
|
32
|
-
expect(http).to receive(:get_content).with(uri.to_s, query: nil, header: nil)
|
33
|
-
.and_raise(OpenSSL::OpenSSLError.new('hostname does not match with server certificate'))
|
34
|
-
expect { client.get(uri) }.to raise_error do |error|
|
35
|
-
expect(error).to be_a(Puppet::Error)
|
36
|
-
expect(error.message).to include("Server hostname 'foo.com' did not match")
|
37
|
-
expect(error.message).to include('expected bar.com')
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
it 're-raises errors it does not understand' do
|
42
|
-
expect(http).to receive(:get_content).with(uri.to_s, query: nil, header: nil)
|
43
|
-
.and_raise(OpenSSL::OpenSSLError.new('other ssl error'))
|
44
|
-
expect{ client.get(uri) }.to raise_error do |error|
|
45
|
-
expect(error).to be_a(OpenSSL::OpenSSLError)
|
46
|
-
expect(error.message).to include('other ssl error')
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
context 'when creating a new client' do
|
52
|
-
let(:ssl_store) { double('store') }
|
53
|
-
let(:ssl_config) do
|
54
|
-
double(
|
55
|
-
'ssl config',
|
56
|
-
:cert_store= => nil,
|
57
|
-
:verify_callback= => nil,
|
58
|
-
:verify_mode= => nil,
|
59
|
-
)
|
60
|
-
end
|
61
|
-
let(:http) do
|
62
|
-
double(
|
63
|
-
'http',
|
64
|
-
:connect_timeout= => nil,
|
65
|
-
:receive_timeout= => nil,
|
66
|
-
:ssl_config => ssl_config,
|
67
|
-
:tcp_keepalive= => nil,
|
68
|
-
:transparent_gzip_decompression= => nil,
|
69
|
-
)
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'initializes itself with basic defaults' do
|
73
|
-
expect(HTTPClient).to receive(:new).and_return(http)
|
74
|
-
# Configure connection with HTTP settings
|
75
|
-
Puppet[:http_read_timeout] = 120
|
76
|
-
Puppet[:http_connect_timeout] = 10
|
77
|
-
Puppet[:http_debug] = true
|
78
|
-
|
79
|
-
expect(http).to receive(:connect_timeout=).with(10)
|
80
|
-
expect(http).to receive(:receive_timeout=).with(120)
|
81
|
-
expect(http).to receive(:debug_dev=).with($stderr)
|
82
|
-
|
83
|
-
# Configure verify mode with SSL settings
|
84
|
-
expect(ssl_config).to receive(:cert_store=).with(ssl_store)
|
85
|
-
Puppet[:ssl_client_ca_auth] = '/fake/path'
|
86
|
-
Puppet[:hostcert] = '/fake/cert/path'
|
87
|
-
expect(ssl_config).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
88
|
-
|
89
|
-
Puppet::Rest::Client.new(ssl_context: Puppet::SSL::SSLContext.new(verify_peer: false, store: ssl_store))
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'uses a given client and SSL store when provided' do
|
93
|
-
expect(ssl_config).to receive(:cert_store=).with(ssl_store)
|
94
|
-
Puppet::Rest::Client.new(client: http,
|
95
|
-
ssl_context: Puppet::SSL::SSLContext.new(verify_peer: true, store: ssl_store))
|
96
|
-
end
|
97
|
-
|
98
|
-
it 'configures a receive timeout when provided' do
|
99
|
-
expect(http).to receive(:receive_timeout=).with(10)
|
100
|
-
Puppet::Rest::Client.new(ssl_context: Puppet::SSL::SSLContext.new(verify_peer: false),
|
101
|
-
client: http, receive_timeout: 10)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
context 'when making requests' do
|
106
|
-
let(:ssl_config) do
|
107
|
-
double(
|
108
|
-
'ssl config',
|
109
|
-
:cert_store= => nil,
|
110
|
-
:verify_callback= => nil,
|
111
|
-
:verify_mode= => nil,
|
112
|
-
)
|
113
|
-
end
|
114
|
-
let(:http) do
|
115
|
-
double(
|
116
|
-
'http',
|
117
|
-
:connect_timeout= => nil,
|
118
|
-
:receive_timeout= => nil,
|
119
|
-
:ssl_config => ssl_config,
|
120
|
-
:tcp_keepalive= => nil,
|
121
|
-
:transparent_gzip_decompression= => nil,
|
122
|
-
)
|
123
|
-
end
|
124
|
-
let(:client) { Puppet::Rest::Client.new(ssl_context: Puppet::SSL::SSLContext.new(verify_peer: false), client: http) }
|
125
|
-
let(:url) { 'https://myserver.com:555/data' }
|
126
|
-
|
127
|
-
describe "#get" do
|
128
|
-
it 'makes a GET request given a URL, query hash, header hash, and streaming block' do
|
129
|
-
query = { 'environment' => 'production' }
|
130
|
-
header = { 'Accept' => 'text/plain' }
|
131
|
-
response_string = ''
|
132
|
-
chunk_processing = lambda { |chunk| response_string = chunk }
|
133
|
-
expect(http).to receive(:get_content).with(url, { query: query, header: header }).and_yield('response')
|
134
|
-
client.get(url, query: query, header: header, &chunk_processing)
|
135
|
-
expect(response_string).to eq('response')
|
136
|
-
end
|
137
|
-
|
138
|
-
it 'throws an exception when the response to the GET is not OK' do
|
139
|
-
fake_response = double('resp', :status => HTTP::Status::BAD_REQUEST)
|
140
|
-
expect(http).to receive(:get_content).with(url, query: nil, header: nil)
|
141
|
-
.and_raise(HTTPClient::BadResponseError.new('failed request', fake_response))
|
142
|
-
expect { client.get(url) }.to raise_error do |error|
|
143
|
-
expect(error.message).to eq('failed request')
|
144
|
-
expect(error.response).to be_a(Puppet::Rest::Response)
|
145
|
-
expect(error.response.status_code).to eq(400)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
include_examples 'connection error handling'
|
150
|
-
end
|
151
|
-
|
152
|
-
describe "#put" do
|
153
|
-
it 'makes a PUT request given a URL, string body, query hash, and header hash' do
|
154
|
-
body = 'send to server'
|
155
|
-
query = { 'environment' => 'production' }
|
156
|
-
header = { 'Accept' => 'text/plain' }
|
157
|
-
expect(http).to receive(:put).with(url, { body: body, query: query, header: header })
|
158
|
-
client.put(url, body: body, query: query, header: header)
|
159
|
-
end
|
160
|
-
|
161
|
-
include_examples 'connection error handling'
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|