puppet 6.11.1 → 6.12.0
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/CODEOWNERS +1 -1
- data/Gemfile +1 -0
- data/Gemfile.lock +16 -16
- data/README.md +1 -1
- data/ext/build_defaults.yaml +1 -0
- data/ext/windows/service/daemon.rb +22 -17
- data/lib/puppet/concurrent.rb +2 -0
- data/lib/puppet/concurrent/lock.rb +16 -0
- data/lib/puppet/concurrent/synchronized.rb +15 -0
- data/lib/puppet/concurrent/thread_local_singleton.rb +14 -0
- data/lib/puppet/configurer.rb +45 -31
- data/lib/puppet/defaults.rb +42 -3
- data/lib/puppet/environments.rb +3 -0
- data/lib/puppet/error.rb +9 -1
- data/lib/puppet/forge.rb +3 -3
- data/lib/puppet/forge/errors.rb +2 -2
- data/lib/puppet/forge/repository.rb +30 -86
- data/lib/puppet/functions/camelcase.rb +2 -2
- data/lib/puppet/functions/epp.rb +4 -4
- data/lib/puppet/functions/find_file.rb +9 -9
- data/lib/puppet/functions/find_template.rb +63 -0
- data/lib/puppet/functions/inline_epp.rb +5 -5
- data/lib/puppet/http.rb +2 -0
- data/lib/puppet/http/client.rb +89 -17
- data/lib/puppet/http/resolver.rb +14 -1
- data/lib/puppet/http/resolver/server_list.rb +38 -0
- data/lib/puppet/http/resolver/settings.rb +3 -2
- data/lib/puppet/http/resolver/srv.rb +10 -4
- data/lib/puppet/http/service.rb +32 -0
- data/lib/puppet/http/service/ca.rb +11 -10
- data/lib/puppet/http/service/report.rb +40 -0
- data/lib/puppet/http/session.rb +11 -32
- data/lib/puppet/network/http/base_pool.rb +13 -0
- data/lib/puppet/node/environment.rb +13 -7
- data/lib/puppet/pal/pal_impl.rb +5 -0
- data/lib/puppet/parser/functions/epp.rb +3 -3
- data/lib/puppet/parser/functions/inline_epp.rb +5 -5
- data/lib/puppet/pops/evaluator/runtime3_support.rb +1 -1
- data/lib/puppet/pops/lookup/invocation.rb +10 -3
- data/lib/puppet/pops/model/pn_transformer.rb +5 -9
- data/lib/puppet/pops/parser/evaluating_parser.rb +3 -4
- data/lib/puppet/pops/serialization/json_path.rb +3 -3
- data/lib/puppet/pops/time/timespan.rb +3 -5
- data/lib/puppet/pops/types/string_converter.rb +6 -9
- data/lib/puppet/pops/types/type_calculator.rb +6 -10
- data/lib/puppet/pops/types/type_formatter.rb +9 -11
- data/lib/puppet/pops/types/type_parser.rb +3 -3
- data/lib/puppet/provider/package/portage.rb +3 -3
- data/lib/puppet/provider/package_targetable.rb +5 -4
- data/lib/puppet/provider/service/systemd.rb +1 -1
- data/lib/puppet/provider/user/hpux.rb +1 -1
- data/lib/puppet/runtime.rb +1 -0
- data/lib/puppet/ssl/ssl_provider.rb +20 -0
- data/lib/puppet/transaction.rb +33 -11
- data/lib/puppet/type.rb +1 -1
- data/lib/puppet/type/file/data_sync.rb +5 -1
- data/lib/puppet/type/group.rb +3 -2
- data/lib/puppet/type/user.rb +3 -2
- data/lib/puppet/util.rb +34 -11
- data/lib/puppet/util/logging.rb +30 -18
- data/lib/puppet/util/windows/adsi.rb +48 -18
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet/x509/cert_provider.rb +9 -5
- data/locales/puppet.pot +155 -141
- data/man/man5/puppet.conf.5 +33 -3
- data/man/man8/puppet-agent.8 +1 -1
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +1 -1
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +1 -1
- data/man/man8/puppet-filebucket.8 +1 -1
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- data/man/man8/puppet-key.8 +1 -1
- data/man/man8/puppet-lookup.8 +1 -1
- data/man/man8/puppet-man.8 +1 -1
- data/man/man8/puppet-module.8 +1 -1
- data/man/man8/puppet-node.8 +1 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +1 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-script.8 +1 -1
- data/man/man8/puppet-ssl.8 +1 -1
- data/man/man8/puppet-status.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/unit/forge/bacula.json +76 -0
- data/spec/integration/http/client_spec.rb +144 -0
- data/spec/integration/module_tool/forge_spec.rb +64 -0
- data/spec/lib/puppet_spec/https.rb +5 -3
- data/spec/spec_helper.rb +6 -2
- data/spec/unit/concurrent/lock_spec.rb +29 -0
- data/spec/unit/configurer_spec.rb +394 -399
- data/spec/unit/defaults_spec.rb +15 -4
- data/spec/unit/forge/errors_spec.rb +1 -1
- data/spec/unit/forge/forge_spec.rb +12 -54
- data/spec/unit/forge/module_release_spec.rb +19 -6
- data/spec/unit/forge/repository_spec.rb +63 -157
- data/spec/unit/forge_spec.rb +46 -116
- data/spec/unit/functions/find_template_spec.rb +69 -0
- data/spec/unit/http/client_spec.rb +138 -6
- data/spec/unit/http/resolver_spec.rb +49 -12
- data/spec/unit/http/service/ca_spec.rb +56 -5
- data/spec/unit/http/service/report_spec.rb +100 -0
- data/spec/unit/http/service_spec.rb +20 -0
- data/spec/unit/http/session_spec.rb +53 -18
- data/spec/unit/network/http/connection_spec.rb +0 -1
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +8 -3
- data/spec/unit/provider/package/portage_spec.rb +4 -4
- data/spec/unit/provider/package_targetable_spec.rb +60 -0
- data/spec/unit/provider/user/hpux_spec.rb +2 -2
- data/spec/unit/ssl/ssl_provider_spec.rb +71 -0
- data/spec/unit/transaction_spec.rb +46 -0
- data/spec/unit/type/file/content_spec.rb +9 -3
- data/spec/unit/util/log_spec.rb +0 -138
- data/spec/unit/util/logging_spec.rb +200 -0
- data/spec/unit/util/windows/adsi_spec.rb +51 -0
- data/spec/unit/x509/cert_provider_spec.rb +24 -4
- data/tasks/manpages.rake +1 -0
- metadata +24 -5
- data/spec/lib/puppet_spec/validators.rb +0 -37
data/spec/unit/defaults_spec.rb
CHANGED
@@ -139,7 +139,7 @@ describe "Defaults" do
|
|
139
139
|
let(:installdir) { 'C:\Program Files\Puppet Labs\Puppet' }
|
140
140
|
|
141
141
|
it 'includes user and system modules' do
|
142
|
-
allow(
|
142
|
+
allow(ENV).to receive(:[]).with("FACTER_env_windows_installdir").and_return(installdir)
|
143
143
|
|
144
144
|
expect(
|
145
145
|
Puppet.default_basemodulepath
|
@@ -147,7 +147,7 @@ describe "Defaults" do
|
|
147
147
|
end
|
148
148
|
|
149
149
|
it 'includes user modules if installdir fact is missing' do
|
150
|
-
allow(
|
150
|
+
allow(ENV).to receive(:[]).with("FACTER_env_windows_installdir").and_return(nil)
|
151
151
|
|
152
152
|
expect(
|
153
153
|
Puppet.default_basemodulepath
|
@@ -167,7 +167,7 @@ describe "Defaults" do
|
|
167
167
|
let(:installdir) { 'C:\Program Files\Puppet Labs\Puppet' }
|
168
168
|
|
169
169
|
it 'includes the default vendormoduledir' do
|
170
|
-
allow(
|
170
|
+
allow(ENV).to receive(:[]).with("FACTER_env_windows_installdir").and_return(installdir)
|
171
171
|
|
172
172
|
expect(
|
173
173
|
Puppet.default_vendormoduledir
|
@@ -175,10 +175,21 @@ describe "Defaults" do
|
|
175
175
|
end
|
176
176
|
|
177
177
|
it 'is nil if installdir fact is missing' do
|
178
|
-
allow(
|
178
|
+
allow(ENV).to receive(:[]).with("FACTER_env_windows_installdir").and_return(nil)
|
179
179
|
|
180
180
|
expect(Puppet.default_vendormoduledir).to be_nil
|
181
181
|
end
|
182
182
|
end
|
183
183
|
end
|
184
|
+
|
185
|
+
describe "facterng", :if => Puppet::Util::Platform.windows? do
|
186
|
+
it "defaults to false" do
|
187
|
+
expect(Puppet[:facterng]).to be_falsey
|
188
|
+
end
|
189
|
+
|
190
|
+
it "raises an exception if facter-ng could not be loaded" do
|
191
|
+
allow(Puppet).to receive(:require).with('facter-ng').and_return(false)
|
192
|
+
expect{ Puppet.settings[:facterng] = true }.to raise_exception ArgumentError, 'facter-ng could not be loaded'
|
193
|
+
end
|
194
|
+
end
|
184
195
|
end
|
@@ -41,7 +41,7 @@ Could not connect to http://fake.com:1111
|
|
41
41
|
|
42
42
|
describe 'ResponseError' do
|
43
43
|
subject { Puppet::Forge::Errors::ResponseError }
|
44
|
-
let(:response) { double(:body => '{}', :code => '404', :
|
44
|
+
let(:response) { double(:body => '{}', :code => '404', :reason => "not found") }
|
45
45
|
|
46
46
|
context 'without message' do
|
47
47
|
let(:exception) { subject.new(:uri => 'http://fake.com:1111', :response => response, :input => 'user/module') }
|
@@ -10,9 +10,8 @@ describe Puppet::Forge do
|
|
10
10
|
ENV['HTTP_PROXY'] = nil
|
11
11
|
end
|
12
12
|
|
13
|
-
let(:host) { 'fake.com' }
|
14
|
-
let(:forge) { Puppet::Forge.new(
|
15
|
-
# creates a repository like Puppet::Forge::Repository.new('http://fake.com', USER_AGENT)
|
13
|
+
let(:host) { 'http://fake.com' }
|
14
|
+
let(:forge) { Puppet::Forge.new(host) }
|
16
15
|
|
17
16
|
# different UTF-8 widths
|
18
17
|
# 1-byte A
|
@@ -22,49 +21,37 @@ describe Puppet::Forge do
|
|
22
21
|
let (:mixed_utf8_query_param) { "foo + A\u06FF\u16A0\u{2070E}" } # Aۿᚠ
|
23
22
|
let (:mixed_utf8_query_param_encoded) { "foo%20%2B%20A%DB%BF%E1%9A%A0%F0%A0%9C%8E"}
|
24
23
|
let (:empty_json) { '{ "results": [], "pagination" : { "next" : null } }' }
|
25
|
-
let (:ok_response) { double('response', :code => '200', :body => empty_json) }
|
26
24
|
|
27
25
|
describe "making a" do
|
28
26
|
before :each do
|
29
|
-
|
27
|
+
Puppet[:http_proxy_host] = "proxy"
|
28
|
+
Puppet[:http_proxy_port] = 1234
|
30
29
|
end
|
31
30
|
|
32
31
|
context "search request" do
|
33
32
|
it "includes any defined module_groups, ensuring to only encode them once in the URI" do
|
34
33
|
Puppet[:module_groups] = 'base+pe'
|
35
|
-
|
36
|
-
|
37
|
-
performs_an_http_request(ok_response) do |http|
|
38
|
-
encoded_uri = "/v3/modules?query=#{mixed_utf8_query_param_encoded}&module_groups=base%20pe"
|
39
|
-
expect(http).to receive(:request).with(have_attributes(path: encoded_uri))
|
40
|
-
end
|
34
|
+
encoded_uri = "#{host}/v3/modules?query=#{mixed_utf8_query_param_encoded}&module_groups=base%20pe"
|
35
|
+
stub_request(:get, encoded_uri).to_return(status: 200, body: empty_json)
|
41
36
|
|
42
37
|
forge.search(mixed_utf8_query_param)
|
43
38
|
end
|
44
39
|
|
45
40
|
it "single encodes the search term in the URI" do
|
46
|
-
|
47
|
-
|
48
|
-
encoded_uri = "/v3/modules?query=#{mixed_utf8_query_param_encoded}"
|
49
|
-
expect(http).to receive(:request).with(have_attributes(path: encoded_uri))
|
50
|
-
end
|
41
|
+
encoded_uri = "#{host}/v3/modules?query=#{mixed_utf8_query_param_encoded}"
|
42
|
+
stub_request(:get, encoded_uri).to_return(status: 200, body: empty_json)
|
51
43
|
|
52
44
|
forge.search(mixed_utf8_query_param)
|
53
45
|
end
|
54
46
|
end
|
55
47
|
|
56
48
|
context "fetch request" do
|
57
|
-
|
58
49
|
it "includes any defined module_groups, ensuring to only encode them once in the URI" do
|
59
50
|
Puppet[:module_groups] = 'base+pe'
|
60
51
|
module_name = 'puppetlabs-acl'
|
61
52
|
exclusions = "readme%2Cchangelog%2Clicense%2Curi%2Cmodule%2Ctags%2Csupported%2Cfile_size%2Cdownloads%2Ccreated_at%2Cupdated_at%2Cdeleted_at"
|
62
|
-
|
63
|
-
|
64
|
-
performs_an_http_request(ok_response) do |http|
|
65
|
-
encoded_uri = "/v3/releases?module=#{module_name}&sort_by=version&exclude_fields=#{exclusions}&module_groups=base%20pe"
|
66
|
-
expect(http).to receive(:request).with(have_attributes(path: encoded_uri))
|
67
|
-
end
|
53
|
+
encoded_uri = "#{host}/v3/releases?module=#{module_name}&sort_by=version&exclude_fields=#{exclusions}&module_groups=base%20pe"
|
54
|
+
stub_request(:get, encoded_uri).to_return(status: 200, body: empty_json)
|
68
55
|
|
69
56
|
forge.fetch(module_name)
|
70
57
|
end
|
@@ -72,40 +59,11 @@ describe Puppet::Forge do
|
|
72
59
|
it "single encodes the module name term in the URI" do
|
73
60
|
module_name = "puppetlabs-#{mixed_utf8_query_param}"
|
74
61
|
exclusions = "readme%2Cchangelog%2Clicense%2Curi%2Cmodule%2Ctags%2Csupported%2Cfile_size%2Cdownloads%2Ccreated_at%2Cupdated_at%2Cdeleted_at"
|
75
|
-
|
76
|
-
|
77
|
-
performs_an_http_request(ok_response) do |http|
|
78
|
-
encoded_uri = "/v3/releases?module=puppetlabs-#{mixed_utf8_query_param_encoded}&sort_by=version&exclude_fields=#{exclusions}"
|
79
|
-
expect(http).to receive(:request).with(have_attributes(path: encoded_uri))
|
80
|
-
end
|
62
|
+
encoded_uri = "#{host}/v3/releases?module=puppetlabs-#{mixed_utf8_query_param_encoded}&sort_by=version&exclude_fields=#{exclusions}"
|
63
|
+
stub_request(:get, encoded_uri).to_return(status: 200, body: empty_json)
|
81
64
|
|
82
65
|
forge.fetch(module_name)
|
83
66
|
end
|
84
67
|
end
|
85
|
-
|
86
|
-
def performs_an_http_request(result = nil, &block)
|
87
|
-
proxy_args = ["proxy", 1234, nil, nil]
|
88
|
-
mock_proxy(80, proxy_args, result, &block)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def proxy_settings_of(host, port)
|
93
|
-
Puppet[:http_proxy_host] = host
|
94
|
-
Puppet[:http_proxy_port] = port
|
95
|
-
end
|
96
|
-
|
97
|
-
def mock_proxy(port, proxy_args, result, &block)
|
98
|
-
http = double("http client")
|
99
|
-
proxy = double("http proxy")
|
100
|
-
|
101
|
-
expect(Net::HTTP).to receive(:new).with(host, port, *proxy_args).and_return(proxy)
|
102
|
-
|
103
|
-
expect(proxy).to receive(:open_timeout=)
|
104
|
-
expect(proxy).to receive(:read_timeout=)
|
105
|
-
|
106
|
-
expect(proxy).to receive(:start).and_yield(http).and_return(result)
|
107
|
-
yield http
|
108
|
-
|
109
|
-
proxy
|
110
68
|
end
|
111
69
|
end
|
@@ -3,8 +3,11 @@ require 'spec_helper'
|
|
3
3
|
require 'puppet/forge'
|
4
4
|
require 'net/http'
|
5
5
|
require 'puppet/module_tool'
|
6
|
+
require 'puppet_spec/files'
|
6
7
|
|
7
8
|
describe Puppet::Forge::ModuleRelease do
|
9
|
+
include PuppetSpec::Files
|
10
|
+
|
8
11
|
let(:agent) { "Test/1.0" }
|
9
12
|
let(:repository) { Puppet::Forge::Repository.new('http://fake.com', agent) }
|
10
13
|
let(:ssl_repository) { Puppet::Forge::Repository.new('https://fake.com', agent) }
|
@@ -27,6 +30,8 @@ describe Puppet::Forge::ModuleRelease do
|
|
27
30
|
|
28
31
|
let(:mock_dir) { '/tmp' }
|
29
32
|
|
33
|
+
let(:destination) { tmpfile('forge_module_release') }
|
34
|
+
|
30
35
|
shared_examples 'a module release' do
|
31
36
|
def mock_digest_file_with_md5(md5)
|
32
37
|
allow(Digest::MD5).to receive(:file).and_return(double(:hexdigest => md5))
|
@@ -40,16 +45,24 @@ describe Puppet::Forge::ModuleRelease do
|
|
40
45
|
end
|
41
46
|
|
42
47
|
describe '#download' do
|
43
|
-
it 'should
|
44
|
-
|
45
|
-
expect(ssl_repository).to receive(:make_http_request).with("/#{api_version}/files/#{module_full_name_versioned}.tar.gz", mock_file).and_return(double(:body => '{}', :code => '200'))
|
48
|
+
it 'should download a file' do
|
49
|
+
stub_request(:get, "https://fake.com/#{api_version}/files/#{module_full_name_versioned}.tar.gz").to_return(status: 200, body: '{}')
|
46
50
|
|
47
|
-
|
51
|
+
File.open(destination, 'wb') do |fh|
|
52
|
+
release.send(:download, "/#{api_version}/files/#{module_full_name_versioned}.tar.gz", fh)
|
53
|
+
end
|
54
|
+
|
55
|
+
expect(File.read(destination)).to eq("{}")
|
48
56
|
end
|
49
57
|
|
50
58
|
it 'should raise a response error when it receives an error from forge' do
|
51
|
-
|
52
|
-
|
59
|
+
stub_request(:get, "https://fake.com/some/path").to_return(
|
60
|
+
status: [500, 'server error'],
|
61
|
+
body: '{"error":"invalid module"}'
|
62
|
+
)
|
63
|
+
expect {
|
64
|
+
release.send(:download, "/some/path", StringIO.new)
|
65
|
+
}.to raise_error Puppet::Forge::Errors::ResponseError
|
53
66
|
end
|
54
67
|
end
|
55
68
|
|
@@ -13,7 +13,6 @@ describe Puppet::Forge::Repository do
|
|
13
13
|
end
|
14
14
|
let(:agent) { "Test/1.0" }
|
15
15
|
let(:repository) { Puppet::Forge::Repository.new('http://fake.com', agent) }
|
16
|
-
let(:ssl_repository) { Puppet::Forge::Repository.new('https://fake.com', agent) }
|
17
16
|
|
18
17
|
it "retrieve accesses the cache" do
|
19
18
|
path = '/module/foo.tar.gz'
|
@@ -34,215 +33,122 @@ describe Puppet::Forge::Repository do
|
|
34
33
|
end
|
35
34
|
|
36
35
|
describe "making a request" do
|
37
|
-
|
38
|
-
proxy_settings_of("proxy", 1234)
|
39
|
-
end
|
36
|
+
let(:uri) { "http://fake.com/the_path" }
|
40
37
|
|
41
|
-
it "returns the
|
42
|
-
|
38
|
+
it "returns the response object from the request" do
|
39
|
+
stub_request(:get, uri)
|
43
40
|
|
44
|
-
|
45
|
-
|
46
|
-
end
|
41
|
+
expect(repository.make_http_request("/the_path")).to be_a_kind_of(Puppet::HTTP::Response)
|
42
|
+
end
|
47
43
|
|
48
|
-
|
44
|
+
it "requires path to have a leading slash" do
|
45
|
+
expect {
|
46
|
+
repository.make_http_request("the_path")
|
47
|
+
}.to raise_error(ArgumentError, 'Path must start with forward slash')
|
49
48
|
end
|
50
49
|
|
51
50
|
it "merges forge URI and path specified" do
|
52
|
-
|
53
|
-
|
54
|
-
performs_an_http_request result do |http|
|
55
|
-
expect(http).to receive(:request).with(have_attributes(path: "/test/the_path/"))
|
56
|
-
end
|
51
|
+
stub_request(:get, "http://fake.com/test/the_path/")
|
57
52
|
|
58
53
|
repository = Puppet::Forge::Repository.new('http://fake.com/test', agent)
|
59
|
-
|
54
|
+
repository.make_http_request("/the_path/")
|
60
55
|
end
|
61
56
|
|
62
57
|
it "handles trailing slashes when merging URI and path" do
|
63
|
-
|
64
|
-
|
65
|
-
performs_an_http_request result do |http|
|
66
|
-
expect(http).to receive(:request).with(have_attributes(path: "/test/the_path"))
|
67
|
-
end
|
58
|
+
stub_request(:get, "http://fake.com/test/the_path")
|
68
59
|
|
69
60
|
repository = Puppet::Forge::Repository.new('http://fake.com/test/', agent)
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'returns the result object from a request with ssl' do
|
74
|
-
result = "#{Object.new}"
|
75
|
-
performs_an_https_request result do |http|
|
76
|
-
expect(http).to receive(:request).with(have_attributes(path: "the_path"))
|
77
|
-
end
|
78
|
-
|
79
|
-
expect(ssl_repository.make_http_request("the_path")).to eq(result)
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'return a valid exception when there is an SSL verification problem' do
|
83
|
-
performs_an_https_request "#{Object.new}" do |http|
|
84
|
-
expect(http).to receive(:request).with(have_attributes(path: "the_path")).and_raise(OpenSSL::SSL::SSLError.new("certificate verify failed"))
|
85
|
-
end
|
86
|
-
|
87
|
-
expect { ssl_repository.make_http_request("the_path") }.to raise_error Puppet::Forge::Errors::SSLVerifyError, 'Unable to verify the SSL certificate at https://fake.com'
|
61
|
+
repository.make_http_request("/the_path")
|
88
62
|
end
|
89
63
|
|
90
64
|
it 'return a valid exception when there is a communication problem' do
|
91
|
-
|
92
|
-
expect(http).to receive(:request).with(have_attributes(path: "the_path")).and_raise(SocketError)
|
93
|
-
end
|
65
|
+
stub_request(:get, uri).to_raise(SocketError.new('getaddrinfo: Name or service not known'))
|
94
66
|
|
95
|
-
expect {
|
96
|
-
|
97
|
-
|
67
|
+
expect {
|
68
|
+
repository.make_http_request("/the_path")
|
69
|
+
}.to raise_error(Puppet::Forge::Errors::CommunicationError,
|
70
|
+
%r{Unable to connect to the server at http://fake.com. Detail: Request to http://fake.com/the_path failed after .* seconds: getaddrinfo: Name or service not known.})
|
98
71
|
end
|
99
72
|
|
100
73
|
it "sets the user agent for the request" do
|
101
|
-
|
102
|
-
|
103
|
-
|
74
|
+
stub_request(:get, uri).with do |request|
|
75
|
+
expect(request.headers['User-Agent']).to match(/#{agent} #{Regexp.escape(Puppet[:http_user_agent])}/)
|
76
|
+
end
|
104
77
|
|
105
|
-
|
106
|
-
expect(request['User-Agent']).to match(/\bPuppet\b/)
|
107
|
-
expect(request['User-Agent']).to match(/\bRuby\b/)
|
78
|
+
repository.make_http_request("/the_path")
|
108
79
|
end
|
109
80
|
|
110
|
-
it "
|
81
|
+
it "does not set Authorization header by default" do
|
111
82
|
allow(Puppet.features).to receive(:pe_license?).and_return(false)
|
112
83
|
Puppet[:forge_authorization] = nil
|
113
|
-
request = repository.get_request_object("the_path")
|
114
|
-
expect(request['Authorization']).to eq(nil)
|
115
|
-
end
|
116
84
|
|
117
|
-
|
118
|
-
|
119
|
-
Puppet[:forge_authorization] = token
|
120
|
-
request = repository.get_request_object("the_path")
|
121
|
-
expect(request['Authorization']).to eq(token)
|
122
|
-
end
|
123
|
-
|
124
|
-
it "encodes the received URI" do
|
125
|
-
unescaped_uri = "héllo world !! ç à"
|
126
|
-
performs_an_http_request do |http|
|
127
|
-
expect(http).to receive(:request).with(have_attributes(path: Puppet::Util.uri_encode(unescaped_uri)))
|
85
|
+
stub_request(:get, uri).with do |request|
|
86
|
+
expect(request.headers).to_not include('Authorization')
|
128
87
|
end
|
129
88
|
|
130
|
-
repository.make_http_request(
|
89
|
+
repository.make_http_request("/the_path")
|
131
90
|
end
|
132
91
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
end
|
92
|
+
it "sets Authorization header from config" do
|
93
|
+
token = 'bearer some token'
|
94
|
+
Puppet[:forge_authorization] = token
|
137
95
|
|
138
|
-
|
139
|
-
proxy_args = ["proxy", 1234, nil, nil]
|
140
|
-
proxy = mock_proxy(443, proxy_args, result, &block)
|
141
|
-
expect(proxy).to receive(:use_ssl=).with(true)
|
142
|
-
expect(proxy).to receive(:cert_store=)
|
143
|
-
expect(proxy).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
|
144
|
-
end
|
145
|
-
end
|
96
|
+
stub_request(:get, uri).with(headers: {'Authorization' => token})
|
146
97
|
|
147
|
-
|
148
|
-
before :each do
|
149
|
-
authenticated_proxy_settings_of("proxy", 1234, 'user1', 'password')
|
98
|
+
repository.make_http_request("/the_path")
|
150
99
|
end
|
151
100
|
|
152
|
-
it "
|
153
|
-
|
101
|
+
it "sets Authorization header from PE license" do
|
102
|
+
allow(Puppet.features).to receive(:pe_license?).and_return(true)
|
103
|
+
stub_const("PELicense", double(load_license_key: double(authorization_token: "opensesame")))
|
154
104
|
|
155
|
-
|
156
|
-
expect(http).to receive(:request).with(have_attributes(path: "the_path"))
|
157
|
-
end
|
105
|
+
stub_request(:get, uri).with(headers: {'Authorization' => "opensesame"})
|
158
106
|
|
159
|
-
|
107
|
+
repository.make_http_request("/the_path")
|
160
108
|
end
|
161
109
|
|
162
|
-
it
|
163
|
-
|
164
|
-
performs_an_authenticated_https_request result do |http|
|
165
|
-
expect(http).to receive(:request).with(have_attributes(path: "the_path"))
|
166
|
-
end
|
110
|
+
it "sets basic authentication if there isn't forge authorization or PE license" do
|
111
|
+
stub_request(:get, uri).with(basic_auth: ['user1', 'password'])
|
167
112
|
|
168
|
-
|
113
|
+
repository = Puppet::Forge::Repository.new('http://user1:password@fake.com', agent)
|
114
|
+
repository.make_http_request("/the_path")
|
169
115
|
end
|
170
116
|
|
171
|
-
it
|
172
|
-
|
173
|
-
|
174
|
-
|
117
|
+
it "omits basic authentication if there is a forge authorization" do
|
118
|
+
token = 'bearer some token'
|
119
|
+
Puppet[:forge_authorization] = token
|
120
|
+
stub_request(:get, uri).with(headers: {'Authorization' => token})
|
175
121
|
|
176
|
-
|
122
|
+
repository = Puppet::Forge::Repository.new('http://user1:password@fake.com', agent)
|
123
|
+
repository.make_http_request("/the_path")
|
177
124
|
end
|
178
125
|
|
179
|
-
it
|
180
|
-
|
181
|
-
expect(http).to receive(:request).with(have_attributes(path: "the_path")).and_raise(SocketError)
|
182
|
-
end
|
126
|
+
it "encodes the URI path" do
|
127
|
+
stub_request(:get, "http://fake.com/h%C3%A9llo%20world%20!!%20%C3%A7%20%C3%A0")
|
183
128
|
|
184
|
-
|
185
|
-
to raise_error Puppet::Forge::Errors::CommunicationError,
|
186
|
-
'Unable to connect to the server at http://fake.com. Detail: SocketError.'
|
129
|
+
repository.make_http_request("/héllo world !! ç à")
|
187
130
|
end
|
188
131
|
|
189
|
-
it "
|
190
|
-
|
132
|
+
it "connects via proxy" do
|
133
|
+
Puppet[:http_proxy_host] = 'proxy'
|
134
|
+
Puppet[:http_proxy_port] = 1234
|
191
135
|
|
192
|
-
|
136
|
+
stub_request(:get, uri)
|
137
|
+
expect(Net::HTTP).to receive(:new).with(anything, anything, 'proxy', 1234, nil, nil).and_call_original
|
193
138
|
|
194
|
-
|
195
|
-
expect(request['User-Agent']).to match(/\bPuppet\b/)
|
196
|
-
expect(request['User-Agent']).to match(/\bRuby\b/)
|
139
|
+
repository.make_http_request("/the_path")
|
197
140
|
end
|
198
141
|
|
199
|
-
it "
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
142
|
+
it "connects via authenticating proxy" do
|
143
|
+
Puppet[:http_proxy_host] = 'proxy'
|
144
|
+
Puppet[:http_proxy_port] = 1234
|
145
|
+
Puppet[:http_proxy_user] = 'user1'
|
146
|
+
Puppet[:http_proxy_password] = 'password'
|
204
147
|
|
205
|
-
|
206
|
-
|
148
|
+
stub_request(:get, uri)
|
149
|
+
expect(Net::HTTP).to receive(:new).with(anything, anything, 'proxy', 1234, "user1", "password").and_call_original
|
207
150
|
|
208
|
-
|
209
|
-
proxy_args = ["proxy", 1234, 'user1', 'password']
|
210
|
-
mock_proxy(80, proxy_args, result, &block)
|
151
|
+
repository.make_http_request("/the_path")
|
211
152
|
end
|
212
|
-
|
213
|
-
def performs_an_authenticated_https_request(result = nil, &block)
|
214
|
-
proxy_args = ["proxy", 1234, 'user1', 'password']
|
215
|
-
proxy = mock_proxy(443, proxy_args, result, &block)
|
216
|
-
expect(proxy).to receive(:use_ssl=).with(true)
|
217
|
-
expect(proxy).to receive(:cert_store=)
|
218
|
-
expect(proxy).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
def proxy_settings_of(host, port)
|
223
|
-
Puppet[:http_proxy_host] = host
|
224
|
-
Puppet[:http_proxy_port] = port
|
225
|
-
end
|
226
|
-
|
227
|
-
def authenticated_proxy_settings_of(host, port, user, password)
|
228
|
-
Puppet[:http_proxy_host] = host
|
229
|
-
Puppet[:http_proxy_port] = port
|
230
|
-
Puppet[:http_proxy_user] = user
|
231
|
-
Puppet[:http_proxy_password] = password
|
232
|
-
end
|
233
|
-
|
234
|
-
def mock_proxy(port, proxy_args, result, &block)
|
235
|
-
http = double("http client")
|
236
|
-
proxy = double("http proxy")
|
237
|
-
|
238
|
-
expect(Net::HTTP).to receive(:new).with("fake.com", port, *proxy_args).and_return(proxy)
|
239
|
-
|
240
|
-
expect(proxy).to receive(:open_timeout=)
|
241
|
-
expect(proxy).to receive(:read_timeout=)
|
242
|
-
|
243
|
-
expect(proxy).to receive(:start).and_yield(http).and_return(result)
|
244
|
-
yield http
|
245
|
-
|
246
|
-
proxy
|
247
153
|
end
|
248
154
|
end
|