puppet 6.4.1-universal-darwin → 6.4.2-universal-darwin
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: universal-darwin
|
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
|
@@ -1093,7 +1093,6 @@ files:
|
|
1093
1093
|
- lib/puppet/resource/status.rb
|
1094
1094
|
- lib/puppet/resource/type.rb
|
1095
1095
|
- lib/puppet/resource/type_collection.rb
|
1096
|
-
- lib/puppet/rest/client.rb
|
1097
1096
|
- lib/puppet/rest/errors.rb
|
1098
1097
|
- lib/puppet/rest/response.rb
|
1099
1098
|
- lib/puppet/rest/route.rb
|
@@ -1799,7 +1798,6 @@ files:
|
|
1799
1798
|
- spec/integration/reports_spec.rb
|
1800
1799
|
- spec/integration/resource/catalog_spec.rb
|
1801
1800
|
- spec/integration/resource/type_collection_spec.rb
|
1802
|
-
- spec/integration/rest/client_spec.rb
|
1803
1801
|
- spec/integration/ssl/certificate_request_spec.rb
|
1804
1802
|
- spec/integration/ssl/host_spec.rb
|
1805
1803
|
- spec/integration/ssl/key_spec.rb
|
@@ -2410,7 +2408,6 @@ files:
|
|
2410
2408
|
- spec/unit/resource/type_collection_spec.rb
|
2411
2409
|
- spec/unit/resource/type_spec.rb
|
2412
2410
|
- spec/unit/resource_spec.rb
|
2413
|
-
- spec/unit/rest/client_spec.rb
|
2414
2411
|
- spec/unit/rest/route_spec.rb
|
2415
2412
|
- spec/unit/scheduler/job_spec.rb
|
2416
2413
|
- spec/unit/scheduler/scheduler_spec.rb
|
@@ -3037,7 +3034,6 @@ test_files:
|
|
3037
3034
|
- spec/integration/reports_spec.rb
|
3038
3035
|
- spec/integration/resource/catalog_spec.rb
|
3039
3036
|
- spec/integration/resource/type_collection_spec.rb
|
3040
|
-
- spec/integration/rest/client_spec.rb
|
3041
3037
|
- spec/integration/ssl/certificate_request_spec.rb
|
3042
3038
|
- spec/integration/ssl/host_spec.rb
|
3043
3039
|
- spec/integration/ssl/key_spec.rb
|
@@ -3648,7 +3644,6 @@ test_files:
|
|
3648
3644
|
- spec/unit/resource/type_collection_spec.rb
|
3649
3645
|
- spec/unit/resource/type_spec.rb
|
3650
3646
|
- spec/unit/resource_spec.rb
|
3651
|
-
- spec/unit/rest/client_spec.rb
|
3652
3647
|
- spec/unit/rest/route_spec.rb
|
3653
3648
|
- spec/unit/scheduler/job_spec.rb
|
3654
3649
|
- 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
|