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.

Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +1 -1
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +16 -16
  5. data/README.md +1 -1
  6. data/ext/build_defaults.yaml +1 -0
  7. data/ext/windows/service/daemon.rb +22 -17
  8. data/lib/puppet/concurrent.rb +2 -0
  9. data/lib/puppet/concurrent/lock.rb +16 -0
  10. data/lib/puppet/concurrent/synchronized.rb +15 -0
  11. data/lib/puppet/concurrent/thread_local_singleton.rb +14 -0
  12. data/lib/puppet/configurer.rb +45 -31
  13. data/lib/puppet/defaults.rb +42 -3
  14. data/lib/puppet/environments.rb +3 -0
  15. data/lib/puppet/error.rb +9 -1
  16. data/lib/puppet/forge.rb +3 -3
  17. data/lib/puppet/forge/errors.rb +2 -2
  18. data/lib/puppet/forge/repository.rb +30 -86
  19. data/lib/puppet/functions/camelcase.rb +2 -2
  20. data/lib/puppet/functions/epp.rb +4 -4
  21. data/lib/puppet/functions/find_file.rb +9 -9
  22. data/lib/puppet/functions/find_template.rb +63 -0
  23. data/lib/puppet/functions/inline_epp.rb +5 -5
  24. data/lib/puppet/http.rb +2 -0
  25. data/lib/puppet/http/client.rb +89 -17
  26. data/lib/puppet/http/resolver.rb +14 -1
  27. data/lib/puppet/http/resolver/server_list.rb +38 -0
  28. data/lib/puppet/http/resolver/settings.rb +3 -2
  29. data/lib/puppet/http/resolver/srv.rb +10 -4
  30. data/lib/puppet/http/service.rb +32 -0
  31. data/lib/puppet/http/service/ca.rb +11 -10
  32. data/lib/puppet/http/service/report.rb +40 -0
  33. data/lib/puppet/http/session.rb +11 -32
  34. data/lib/puppet/network/http/base_pool.rb +13 -0
  35. data/lib/puppet/node/environment.rb +13 -7
  36. data/lib/puppet/pal/pal_impl.rb +5 -0
  37. data/lib/puppet/parser/functions/epp.rb +3 -3
  38. data/lib/puppet/parser/functions/inline_epp.rb +5 -5
  39. data/lib/puppet/pops/evaluator/runtime3_support.rb +1 -1
  40. data/lib/puppet/pops/lookup/invocation.rb +10 -3
  41. data/lib/puppet/pops/model/pn_transformer.rb +5 -9
  42. data/lib/puppet/pops/parser/evaluating_parser.rb +3 -4
  43. data/lib/puppet/pops/serialization/json_path.rb +3 -3
  44. data/lib/puppet/pops/time/timespan.rb +3 -5
  45. data/lib/puppet/pops/types/string_converter.rb +6 -9
  46. data/lib/puppet/pops/types/type_calculator.rb +6 -10
  47. data/lib/puppet/pops/types/type_formatter.rb +9 -11
  48. data/lib/puppet/pops/types/type_parser.rb +3 -3
  49. data/lib/puppet/provider/package/portage.rb +3 -3
  50. data/lib/puppet/provider/package_targetable.rb +5 -4
  51. data/lib/puppet/provider/service/systemd.rb +1 -1
  52. data/lib/puppet/provider/user/hpux.rb +1 -1
  53. data/lib/puppet/runtime.rb +1 -0
  54. data/lib/puppet/ssl/ssl_provider.rb +20 -0
  55. data/lib/puppet/transaction.rb +33 -11
  56. data/lib/puppet/type.rb +1 -1
  57. data/lib/puppet/type/file/data_sync.rb +5 -1
  58. data/lib/puppet/type/group.rb +3 -2
  59. data/lib/puppet/type/user.rb +3 -2
  60. data/lib/puppet/util.rb +34 -11
  61. data/lib/puppet/util/logging.rb +30 -18
  62. data/lib/puppet/util/windows/adsi.rb +48 -18
  63. data/lib/puppet/version.rb +1 -1
  64. data/lib/puppet/x509/cert_provider.rb +9 -5
  65. data/locales/puppet.pot +155 -141
  66. data/man/man5/puppet.conf.5 +33 -3
  67. data/man/man8/puppet-agent.8 +1 -1
  68. data/man/man8/puppet-apply.8 +1 -1
  69. data/man/man8/puppet-catalog.8 +1 -1
  70. data/man/man8/puppet-config.8 +1 -1
  71. data/man/man8/puppet-describe.8 +1 -1
  72. data/man/man8/puppet-device.8 +1 -1
  73. data/man/man8/puppet-doc.8 +1 -1
  74. data/man/man8/puppet-epp.8 +1 -1
  75. data/man/man8/puppet-facts.8 +1 -1
  76. data/man/man8/puppet-filebucket.8 +1 -1
  77. data/man/man8/puppet-generate.8 +1 -1
  78. data/man/man8/puppet-help.8 +1 -1
  79. data/man/man8/puppet-key.8 +1 -1
  80. data/man/man8/puppet-lookup.8 +1 -1
  81. data/man/man8/puppet-man.8 +1 -1
  82. data/man/man8/puppet-module.8 +1 -1
  83. data/man/man8/puppet-node.8 +1 -1
  84. data/man/man8/puppet-parser.8 +1 -1
  85. data/man/man8/puppet-plugin.8 +1 -1
  86. data/man/man8/puppet-report.8 +1 -1
  87. data/man/man8/puppet-resource.8 +1 -1
  88. data/man/man8/puppet-script.8 +1 -1
  89. data/man/man8/puppet-ssl.8 +1 -1
  90. data/man/man8/puppet-status.8 +1 -1
  91. data/man/man8/puppet.8 +2 -2
  92. data/spec/fixtures/unit/forge/bacula.json +76 -0
  93. data/spec/integration/http/client_spec.rb +144 -0
  94. data/spec/integration/module_tool/forge_spec.rb +64 -0
  95. data/spec/lib/puppet_spec/https.rb +5 -3
  96. data/spec/spec_helper.rb +6 -2
  97. data/spec/unit/concurrent/lock_spec.rb +29 -0
  98. data/spec/unit/configurer_spec.rb +394 -399
  99. data/spec/unit/defaults_spec.rb +15 -4
  100. data/spec/unit/forge/errors_spec.rb +1 -1
  101. data/spec/unit/forge/forge_spec.rb +12 -54
  102. data/spec/unit/forge/module_release_spec.rb +19 -6
  103. data/spec/unit/forge/repository_spec.rb +63 -157
  104. data/spec/unit/forge_spec.rb +46 -116
  105. data/spec/unit/functions/find_template_spec.rb +69 -0
  106. data/spec/unit/http/client_spec.rb +138 -6
  107. data/spec/unit/http/resolver_spec.rb +49 -12
  108. data/spec/unit/http/service/ca_spec.rb +56 -5
  109. data/spec/unit/http/service/report_spec.rb +100 -0
  110. data/spec/unit/http/service_spec.rb +20 -0
  111. data/spec/unit/http/session_spec.rb +53 -18
  112. data/spec/unit/network/http/connection_spec.rb +0 -1
  113. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +8 -3
  114. data/spec/unit/provider/package/portage_spec.rb +4 -4
  115. data/spec/unit/provider/package_targetable_spec.rb +60 -0
  116. data/spec/unit/provider/user/hpux_spec.rb +2 -2
  117. data/spec/unit/ssl/ssl_provider_spec.rb +71 -0
  118. data/spec/unit/transaction_spec.rb +46 -0
  119. data/spec/unit/type/file/content_spec.rb +9 -3
  120. data/spec/unit/util/log_spec.rb +0 -138
  121. data/spec/unit/util/logging_spec.rb +200 -0
  122. data/spec/unit/util/windows/adsi_spec.rb +51 -0
  123. data/spec/unit/x509/cert_provider_spec.rb +24 -4
  124. data/tasks/manpages.rake +1 -0
  125. metadata +24 -5
  126. data/spec/lib/puppet_spec/validators.rb +0 -37
@@ -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(Facter).to receive(:value).with(:env_windows_installdir).and_return(installdir)
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(Facter).to receive(:value).with(:env_windows_installdir).and_return(nil)
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(Facter).to receive(:value).with(:env_windows_installdir).and_return(installdir)
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(Facter).to receive(:value).with(:env_windows_installdir).and_return(nil)
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', :message => "not found") }
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("http://#{host}") }
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
- proxy_settings_of("proxy", 1234)
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
- # ignores Puppet::Forge::Repository#read_response, provides response to search
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
- # ignores Puppet::Forge::Repository#read_response, provides response to search
47
- performs_an_http_request(ok_response) do |http|
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
- # ignores Puppet::Forge::Repository#read_response, provides response to fetch
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
- # ignores Puppet::Forge::Repository#read_response, provides response to fetch
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 call make_http_request with correct params' do
44
- # valid URI comes from file_uri in JSON blob above
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
- release.send(:download, "/#{api_version}/files/#{module_full_name_versioned}.tar.gz", mock_file)
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
- allow(ssl_repository).to receive(:make_http_request).and_return(double(:body => '{"errors": ["error"]}', :code => '500', :message => 'server error'))
52
- expect { release.send(:download, "/some/path", mock_file)}.to raise_error Puppet::Forge::Errors::ResponseError
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
- before :each do
38
- proxy_settings_of("proxy", 1234)
39
- end
36
+ let(:uri) { "http://fake.com/the_path" }
40
37
 
41
- it "returns the result object from the request" do
42
- result = "#{Object.new}"
38
+ it "returns the response object from the request" do
39
+ stub_request(:get, uri)
43
40
 
44
- performs_an_http_request result do |http|
45
- expect(http).to receive(:request).with(have_attributes(path: "the_path"))
46
- end
41
+ expect(repository.make_http_request("/the_path")).to be_a_kind_of(Puppet::HTTP::Response)
42
+ end
47
43
 
48
- expect(repository.make_http_request("the_path")).to eq(result)
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
- result = "#{Object.new}"
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
- expect(repository.make_http_request("/the_path/")).to eq(result)
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
- result = "#{Object.new}"
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
- expect(repository.make_http_request("/the_path")).to eq(result)
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
- performs_an_http_request "#{Object.new}" do |http|
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 { repository.make_http_request("the_path") }.
96
- to raise_error Puppet::Forge::Errors::CommunicationError,
97
- 'Unable to connect to the server at http://fake.com. Detail: SocketError.'
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
- path = 'the_path'
102
-
103
- request = repository.get_request_object(path)
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
- expect(request['User-Agent']).to match(/\b#{agent}\b/)
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 "Does not set Authorization header by default" do
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
- it "Sets Authorization header from config" do
118
- token = 'bearer some token'
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(unescaped_uri)
89
+ repository.make_http_request("/the_path")
131
90
  end
132
91
 
133
- def performs_an_http_request(result = nil, &block)
134
- proxy_args = ["proxy", 1234, nil, nil]
135
- mock_proxy(80, proxy_args, result, &block)
136
- end
92
+ it "sets Authorization header from config" do
93
+ token = 'bearer some token'
94
+ Puppet[:forge_authorization] = token
137
95
 
138
- def performs_an_https_request(result = nil, &block)
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
- describe "making a request against an authentiated proxy" do
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 "returns the result object from the request" do
153
- result = "#{Object.new}"
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
- performs_an_authenticated_http_request result do |http|
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
- expect(repository.make_http_request("the_path")).to eq(result)
107
+ repository.make_http_request("/the_path")
160
108
  end
161
109
 
162
- it 'returns the result object from a request with ssl' do
163
- result = "#{Object.new}"
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
- expect(ssl_repository.make_http_request("the_path")).to eq(result)
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 'return a valid exception when there is an SSL verification problem' do
172
- performs_an_authenticated_https_request "#{Object.new}" do |http|
173
- expect(http).to receive(:request).with(have_attributes(path: "the_path")).and_raise(OpenSSL::SSL::SSLError.new("certificate verify failed"))
174
- end
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
- 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'
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 'return a valid exception when there is a communication problem' do
180
- performs_an_authenticated_http_request "#{Object.new}" do |http|
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
- expect { repository.make_http_request("the_path") }.
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 "sets the user agent for the request" do
190
- path = 'the_path'
132
+ it "connects via proxy" do
133
+ Puppet[:http_proxy_host] = 'proxy'
134
+ Puppet[:http_proxy_port] = 1234
191
135
 
192
- request = repository.get_request_object(path)
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
- expect(request['User-Agent']).to match(/\b#{agent}\b/)
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 "encodes the received URI" do
200
- unescaped_uri = "héllo world !! ç à"
201
- performs_an_authenticated_http_request do |http|
202
- expect(http).to receive(:request).with(have_attributes(path: Puppet::Util.uri_encode(unescaped_uri)))
203
- end
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
- repository.make_http_request(unescaped_uri)
206
- end
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
- def performs_an_authenticated_http_request(result = nil, &block)
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