puppet 6.14.0 → 6.15.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 (195) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +15 -15
  3. data/ext/windows/service/daemon.rb +3 -3
  4. data/lib/puppet.rb +1 -1
  5. data/lib/puppet/agent.rb +2 -10
  6. data/lib/puppet/application/agent.rb +2 -1
  7. data/lib/puppet/application/filebucket.rb +5 -14
  8. data/lib/puppet/application/ssl.rb +2 -2
  9. data/lib/puppet/configurer.rb +7 -3
  10. data/lib/puppet/configurer/plugin_handler.rb +1 -1
  11. data/lib/puppet/defaults.rb +22 -2
  12. data/lib/puppet/environments.rb +4 -5
  13. data/lib/puppet/face/plugin.rb +1 -1
  14. data/lib/puppet/file_system/file_impl.rb +13 -9
  15. data/lib/puppet/forge/repository.rb +1 -1
  16. data/lib/puppet/functions/call.rb +1 -1
  17. data/lib/puppet/functions/reduce.rb +2 -4
  18. data/lib/puppet/http.rb +2 -0
  19. data/lib/puppet/http/client.rb +191 -52
  20. data/lib/puppet/http/external_client.rb +96 -0
  21. data/lib/puppet/http/redirector.rb +34 -0
  22. data/lib/puppet/http/resolver.rb +46 -3
  23. data/lib/puppet/http/resolver/server_list.rb +75 -15
  24. data/lib/puppet/http/resolver/settings.rb +22 -2
  25. data/lib/puppet/http/resolver/srv.rb +28 -2
  26. data/lib/puppet/http/response.rb +63 -1
  27. data/lib/puppet/http/retry_after_handler.rb +39 -0
  28. data/lib/puppet/http/service.rb +67 -1
  29. data/lib/puppet/http/service/ca.rb +71 -9
  30. data/lib/puppet/http/service/compiler.rb +213 -11
  31. data/lib/puppet/http/service/file_server.rb +105 -4
  32. data/lib/puppet/http/service/report.rb +36 -3
  33. data/lib/puppet/http/session.rb +59 -8
  34. data/lib/puppet/indirector/catalog/rest.rb +2 -1
  35. data/lib/puppet/indirector/facts/rest.rb +2 -1
  36. data/lib/puppet/indirector/file_bucket_file/rest.rb +48 -0
  37. data/lib/puppet/indirector/file_metadata/rest.rb +4 -2
  38. data/lib/puppet/indirector/node/rest.rb +2 -1
  39. data/lib/puppet/indirector/report/yaml.rb +23 -0
  40. data/lib/puppet/indirector/status/rest.rb +2 -1
  41. data/lib/puppet/metatype/manager.rb +80 -80
  42. data/lib/puppet/network/http/base_pool.rb +6 -1
  43. data/lib/puppet/network/http/pool.rb +2 -4
  44. data/lib/puppet/network/http_pool.rb +1 -0
  45. data/lib/puppet/node/environment.rb +11 -1
  46. data/lib/puppet/pal/pal_impl.rb +1 -29
  47. data/lib/puppet/parser/compiler.rb +14 -7
  48. data/lib/puppet/parser/functions.rb +18 -13
  49. data/lib/puppet/pops/loaders.rb +7 -5
  50. data/lib/puppet/provider/group/windows_adsi.rb +3 -3
  51. data/lib/puppet/provider/package/apt.rb +61 -1
  52. data/lib/puppet/provider/package/dnfmodule.rb +39 -12
  53. data/lib/puppet/provider/package/gem.rb +41 -7
  54. data/lib/puppet/provider/package/pacman.rb +2 -5
  55. data/lib/puppet/provider/package/pip.rb +105 -33
  56. data/lib/puppet/provider/package/pip3.rb +0 -2
  57. data/lib/puppet/provider/package/pkgdmg.rb +1 -1
  58. data/lib/puppet/provider/package/pkgng.rb +16 -4
  59. data/lib/puppet/provider/package/puppet_gem.rb +6 -2
  60. data/lib/puppet/provider/package/rpm.rb +6 -213
  61. data/lib/puppet/provider/package/yum.rb +92 -19
  62. data/lib/puppet/provider/service/systemd.rb +2 -1
  63. data/lib/puppet/reports/http.rb +13 -11
  64. data/lib/puppet/resource/type_collection.rb +20 -16
  65. data/lib/puppet/ssl.rb +1 -0
  66. data/lib/puppet/ssl/host.rb +4 -4
  67. data/lib/puppet/ssl/oids.rb +1 -0
  68. data/lib/puppet/ssl/state_machine.rb +50 -33
  69. data/lib/puppet/transaction/report.rb +2 -2
  70. data/lib/puppet/type.rb +6 -1
  71. data/lib/puppet/type/file/source.rb +4 -2
  72. data/lib/puppet/type/package.rb +25 -2
  73. data/lib/puppet/type/user.rb +0 -19
  74. data/lib/puppet/util/at_fork.rb +1 -1
  75. data/lib/puppet/util/autoload.rb +3 -0
  76. data/lib/puppet/util/instance_loader.rb +14 -10
  77. data/lib/puppet/util/package/version/debian.rb +175 -0
  78. data/lib/puppet/util/package/version/gem.rb +15 -0
  79. data/lib/puppet/util/package/version/pip.rb +167 -0
  80. data/lib/puppet/util/package/version/range.rb +50 -0
  81. data/lib/puppet/util/package/version/range/gt.rb +14 -0
  82. data/lib/puppet/util/package/version/range/gt_eq.rb +14 -0
  83. data/lib/puppet/util/package/version/range/lt.rb +14 -0
  84. data/lib/puppet/util/package/version/range/lt_eq.rb +14 -0
  85. data/lib/puppet/util/package/version/range/min_max.rb +21 -0
  86. data/lib/puppet/util/package/version/range/simple.rb +11 -0
  87. data/lib/puppet/util/package/version/rpm.rb +73 -0
  88. data/lib/puppet/util/pidlock.rb +13 -7
  89. data/lib/puppet/util/platform.rb +5 -0
  90. data/lib/puppet/util/rpm_compare.rb +193 -0
  91. data/lib/puppet/util/windows/adsi.rb +2 -2
  92. data/lib/puppet/util/windows/process.rb +15 -14
  93. data/lib/puppet/util/windows/security.rb +1 -0
  94. data/lib/puppet/util/windows/sid.rb +3 -3
  95. data/lib/puppet/version.rb +1 -1
  96. data/locales/puppet.pot +207 -201
  97. data/man/man5/puppet.conf.5 +11 -3
  98. data/man/man8/puppet-agent.8 +1 -1
  99. data/man/man8/puppet-apply.8 +1 -1
  100. data/man/man8/puppet-catalog.8 +1 -1
  101. data/man/man8/puppet-config.8 +1 -1
  102. data/man/man8/puppet-describe.8 +1 -1
  103. data/man/man8/puppet-device.8 +1 -1
  104. data/man/man8/puppet-doc.8 +1 -1
  105. data/man/man8/puppet-epp.8 +1 -1
  106. data/man/man8/puppet-facts.8 +1 -1
  107. data/man/man8/puppet-filebucket.8 +1 -1
  108. data/man/man8/puppet-generate.8 +1 -1
  109. data/man/man8/puppet-help.8 +1 -1
  110. data/man/man8/puppet-key.8 +1 -1
  111. data/man/man8/puppet-lookup.8 +1 -1
  112. data/man/man8/puppet-man.8 +1 -1
  113. data/man/man8/puppet-module.8 +1 -1
  114. data/man/man8/puppet-node.8 +1 -1
  115. data/man/man8/puppet-parser.8 +1 -1
  116. data/man/man8/puppet-plugin.8 +1 -1
  117. data/man/man8/puppet-report.8 +1 -1
  118. data/man/man8/puppet-resource.8 +1 -1
  119. data/man/man8/puppet-script.8 +1 -1
  120. data/man/man8/puppet-ssl.8 +1 -1
  121. data/man/man8/puppet-status.8 +1 -1
  122. data/man/man8/puppet.8 +2 -2
  123. data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +67 -0
  124. data/spec/fixtures/ssl/unknown-127.0.0.1.pem +48 -0
  125. data/spec/fixtures/ssl/unknown-ca-key.pem +67 -0
  126. data/spec/fixtures/ssl/unknown-ca.pem +59 -0
  127. data/spec/fixtures/unit/provider/package/dnfmodule/{dnf-module-list-installed.txt → dnf-module-list-enabled.txt} +2 -0
  128. data/spec/fixtures/unit/provider/package/pkgng/pkg.version +2 -0
  129. data/spec/fixtures/unit/provider/package/yum/yum-check-update-subscription-manager.txt +9 -0
  130. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services +9 -0
  131. data/spec/integration/application/agent_spec.rb +329 -0
  132. data/spec/integration/application/apply_spec.rb +132 -3
  133. data/spec/integration/application/filebucket_spec.rb +190 -0
  134. data/spec/integration/application/plugin_spec.rb +50 -0
  135. data/spec/integration/http/client_spec.rb +34 -40
  136. data/spec/integration/indirector/report/yaml.rb +83 -0
  137. data/spec/integration/module_tool/forge_spec.rb +2 -15
  138. data/spec/integration/network/http_pool_spec.rb +11 -19
  139. data/spec/integration/node/environment_spec.rb +15 -0
  140. data/spec/integration/util/windows/adsi_spec.rb +1 -1
  141. data/spec/lib/puppet/test_ca.rb +2 -2
  142. data/spec/lib/puppet_spec/https.rb +10 -7
  143. data/spec/lib/puppet_spec/puppetserver.rb +119 -0
  144. data/spec/shared_contexts/https.rb +29 -0
  145. data/spec/unit/agent_spec.rb +33 -25
  146. data/spec/unit/application/agent_spec.rb +5 -1
  147. data/spec/unit/application/device_spec.rb +2 -2
  148. data/spec/unit/application/filebucket_spec.rb +22 -2
  149. data/spec/unit/configurer_spec.rb +1 -1
  150. data/spec/unit/defaults_spec.rb +24 -1
  151. data/spec/unit/environments_spec.rb +8 -0
  152. data/spec/unit/file_system_spec.rb +10 -0
  153. data/spec/unit/http/client_spec.rb +105 -46
  154. data/spec/unit/http/external_client_spec.rb +201 -0
  155. data/spec/unit/http/resolver_spec.rb +20 -0
  156. data/spec/unit/http/service/ca_spec.rb +25 -2
  157. data/spec/unit/http/service/compiler_spec.rb +184 -6
  158. data/spec/unit/http/service/file_server_spec.rb +35 -3
  159. data/spec/unit/http/service/report_spec.rb +3 -1
  160. data/spec/unit/http/service_spec.rb +3 -3
  161. data/spec/unit/http/session_spec.rb +56 -7
  162. data/spec/unit/indirector/file_bucket_file/rest_spec.rb +82 -2
  163. data/spec/unit/network/http/pool_spec.rb +3 -3
  164. data/spec/unit/node/environment_spec.rb +16 -0
  165. data/spec/unit/provider/group/windows_adsi_spec.rb +43 -10
  166. data/spec/unit/provider/package/apt_spec.rb +30 -0
  167. data/spec/unit/provider/package/dnfmodule_spec.rb +33 -14
  168. data/spec/unit/provider/package/gem_spec.rb +40 -0
  169. data/spec/unit/provider/package/pacman_spec.rb +6 -21
  170. data/spec/unit/provider/package/pip_spec.rb +26 -3
  171. data/spec/unit/provider/package/pkgdmg_spec.rb +1 -1
  172. data/spec/unit/provider/package/pkgng_spec.rb +38 -0
  173. data/spec/unit/provider/package/puppet_gem_spec.rb +8 -0
  174. data/spec/unit/provider/package/rpm_spec.rb +0 -212
  175. data/spec/unit/provider/package/yum_spec.rb +235 -1
  176. data/spec/unit/provider/service/systemd_spec.rb +10 -1
  177. data/spec/unit/provider/user/windows_adsi_spec.rb +3 -3
  178. data/spec/unit/puppet_pal_2pec.rb +0 -29
  179. data/spec/unit/reports/http_spec.rb +70 -52
  180. data/spec/unit/ssl/host_spec.rb +4 -2
  181. data/spec/unit/ssl/oids_spec.rb +1 -0
  182. data/spec/unit/ssl/state_machine_spec.rb +38 -6
  183. data/spec/unit/transaction/report_spec.rb +4 -0
  184. data/spec/unit/util/at_fork_spec.rb +2 -2
  185. data/spec/unit/util/package/version/debian_spec.rb +83 -0
  186. data/spec/unit/util/package/version/pip_spec.rb +464 -0
  187. data/spec/unit/util/package/version/range_spec.rb +154 -0
  188. data/spec/unit/util/package/version/rpm_spec.rb +121 -0
  189. data/spec/unit/util/pidlock_spec.rb +83 -47
  190. data/spec/unit/util/rpm_compare_spec.rb +196 -0
  191. data/spec/unit/util/windows/adsi_spec.rb +4 -4
  192. data/spec/unit/util/windows/sid_spec.rb +2 -2
  193. data/tasks/generate_cert_fixtures.rake +15 -1
  194. metadata +51 -6
  195. data/spec/integration/faces/plugin_spec.rb +0 -63
@@ -0,0 +1,190 @@
1
+ require 'spec_helper'
2
+ require 'puppet/face'
3
+ require 'puppet_spec/puppetserver'
4
+ require 'puppet_spec/files'
5
+
6
+ describe "puppet filebucket", unless: Puppet::Util::Platform.jruby? do
7
+ include PuppetSpec::Files
8
+ include_context "https client"
9
+
10
+ let(:server) { PuppetSpec::Puppetserver.new }
11
+ let(:filebucket) { Puppet::Application[:filebucket] }
12
+ let(:backup_file) { tmpfile('backup_file') }
13
+
14
+ before :each do
15
+ Puppet[:log_level] = 'debug'
16
+ end
17
+
18
+ it "backs up files to the filebucket server" do
19
+ File.binwrite(backup_file, 'some random text')
20
+ md5 = Digest::MD5.file(backup_file).to_s
21
+
22
+ server.start_server do |port|
23
+ Puppet[:masterport] = port
24
+ expect {
25
+ filebucket.command_line.args << 'backup'
26
+ filebucket.command_line.args << backup_file
27
+ filebucket.run
28
+ }.to output(a_string_matching(
29
+ %r{Debug: HTTP HEAD https:\/\/127.0.0.1:#{port}\/puppet\/v3\/file_bucket_file\/md5\/#{md5}\/#{File.realpath(backup_file)}\?environment\=production returned 404 Not Found}
30
+ ).and matching(
31
+ %r{Debug: HTTP PUT https:\/\/127.0.0.1:#{port}\/puppet\/v3\/file_bucket_file\/md5\/#{md5}\/#{File.realpath(backup_file)}\?environment\=production returned 200 OK}
32
+ ).and matching(
33
+ %r{#{backup_file}: #{md5}}
34
+ )).to_stdout
35
+ end
36
+ end
37
+
38
+ it "doesn't attempt to back up file that already exists on the filebucket server" do
39
+ file_exists_handler = -> (req, res) {
40
+ res.status = 200
41
+ }
42
+
43
+ File.binwrite(backup_file, 'some random text')
44
+ md5 = Digest::MD5.file(backup_file).to_s
45
+
46
+ server.start_server(mounts: {filebucket: file_exists_handler}) do |port|
47
+ Puppet[:masterport] = port
48
+ expect {
49
+ filebucket.command_line.args << 'backup'
50
+ filebucket.command_line.args << backup_file
51
+ filebucket.run
52
+ }.to output(a_string_matching(
53
+ %r{Debug: HTTP HEAD https:\/\/127.0.0.1:#{port}\/puppet\/v3\/file_bucket_file\/md5\/#{md5}\/#{File.realpath(backup_file)}\?environment\=production returned 200 OK}
54
+ ).and matching(
55
+ %r{#{backup_file}: #{md5}}
56
+ )).to_stdout
57
+ end
58
+ end
59
+
60
+ it "downloads files from the filebucket server" do
61
+ get_handler = -> (req, res) {
62
+ res['Content-Type'] = 'application/octet-stream'
63
+ res.body = 'something to store'
64
+ }
65
+
66
+ server.start_server(mounts: {filebucket: get_handler}) do |port|
67
+ Puppet[:masterport] = port
68
+ expect {
69
+ filebucket.command_line.args << 'get'
70
+ filebucket.command_line.args << 'fac251367c9e083c6b1f0f3181'
71
+ filebucket.run
72
+ }.to output(a_string_matching(
73
+ %r{Debug: HTTP GET https:\/\/127.0.0.1:#{port}\/puppet\/v3\/file_bucket_file\/md5\/fac251367c9e083c6b1f0f3181\?environment\=production returned 200 OK}
74
+ ).and matching(
75
+ %r{something to store}
76
+ )).to_stdout
77
+ end
78
+ end
79
+
80
+ context 'diff', unless: Puppet::Util::Platform.windows? || Puppet::Util::Platform.jruby? do
81
+ context 'using a remote bucket' do
82
+ it 'outputs a diff between a local and remote file' do
83
+ File.binwrite(backup_file, "bar\nbaz")
84
+
85
+ get_handler = -> (req, res) {
86
+ res['Content-Type'] = 'application/octet-stream'
87
+ res.body = 'foo'
88
+ }
89
+
90
+ server.start_server(mounts: {filebucket: get_handler}) do |port|
91
+ Puppet[:masterport] = port
92
+ expect {
93
+ filebucket.command_line.args += ['diff', 'fac251367c9e083c6b1f0f3181', backup_file, '--remote']
94
+ filebucket.run
95
+ }.to output(a_string_matching(
96
+ /[-<] ?foo/
97
+ ).and matching(
98
+ /[+>] ?bar/
99
+ ).and matching(
100
+ /[+>] ?baz/
101
+ )).to_stdout
102
+ end
103
+ end
104
+
105
+ it 'outputs a diff between two remote files' do
106
+ get_handler = -> (req, res) {
107
+ res['Content-Type'] = 'application/octet-stream'
108
+ res.body = <<~END
109
+ --- /opt/puppetlabs/server/data/puppetserver/bucket/d/3/b/0/7/3/8/4/d3b07384d113edec49eaa6238ad5ff00/contents\t2020-04-06 21:25:24.892367570 +0000
110
+ +++ /opt/puppetlabs/server/data/puppetserver/bucket/9/9/b/9/9/9/2/0/99b999207e287afffc86c053e5693247/contents\t2020-04-06 21:26:13.603398063 +0000
111
+ @@ -1 +1,2 @@
112
+ -foo
113
+ +bar
114
+ +baz
115
+ END
116
+ }
117
+
118
+ server.start_server(mounts: {filebucket: get_handler}) do |port|
119
+ Puppet[:masterport] = port
120
+ expect {
121
+ filebucket.command_line.args += ['diff', 'd3b07384d113edec49eaa6238ad5ff00', "99b999207e287afffc86c053e5693247", '--remote']
122
+ filebucket.run
123
+ }.to output(a_string_matching(
124
+ /[-<] ?foo/
125
+ ).and matching(
126
+ /[+>] ?bar/
127
+ ).and matching(
128
+ /[+>] ?baz/
129
+ )).to_stdout
130
+ end
131
+ end
132
+ end
133
+
134
+ context 'using a local bucket' do
135
+ let(:filea) {
136
+ f = tmpfile('filea')
137
+ File.binwrite(f, 'foo')
138
+ f
139
+ }
140
+ let(:fileb) {
141
+ f = tmpfile('fileb')
142
+ File.binwrite(f, "bar\nbaz")
143
+ f
144
+ }
145
+ let(:checksuma) { Digest::MD5.file(filea).to_s }
146
+ let(:checksumb) { Digest::MD5.file(fileb).to_s }
147
+
148
+ it 'compares to files stored in a local bucket' do
149
+ expect {
150
+ filebucket.command_line.args = ['backup', filea, '--local']
151
+ filebucket.run
152
+ }.to output(/#{filea}: #{checksuma}/).to_stdout
153
+
154
+ expect{
155
+ filebucket.command_line.args = ['backup', fileb, '--local']
156
+ filebucket.run
157
+ }.to output(/#{fileb}: #{checksumb}\n/).to_stdout
158
+
159
+ expect {
160
+ filebucket.command_line.args = ['diff', checksuma, checksumb, '--local']
161
+ filebucket.run
162
+ }.to output(a_string_matching(
163
+ /[-<] ?foo/
164
+ ).and matching(
165
+ /[+>] ?bar/
166
+ ).and matching(
167
+ /[+>] ?baz/
168
+ )).to_stdout
169
+ end
170
+
171
+ it 'compares a file on the filesystem and a file stored in a local bucket' do
172
+ expect {
173
+ filebucket.command_line.args = ['backup', filea, '--local']
174
+ filebucket.run
175
+ }.to output(/#{filea}: #{checksuma}/).to_stdout
176
+
177
+ expect {
178
+ filebucket.command_line.args = ['diff', checksuma, fileb, '--local']
179
+ filebucket.run
180
+ }.to output(a_string_matching(
181
+ /[-<] ?foo/
182
+ ).and matching(
183
+ /[+>] ?bar/
184
+ ).and matching(
185
+ /[+>] ?baz/
186
+ )).to_stdout
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+ require 'puppet/face'
3
+ require 'puppet_spec/puppetserver'
4
+
5
+ describe "puppet plugin" do
6
+ include_context "https client"
7
+
8
+ let(:server) { PuppetSpec::Puppetserver.new }
9
+ let(:plugin) { Puppet::Application[:plugin] }
10
+ let(:response_body) { "[{\"path\":\"/etc/puppetlabs/code/environments/production/modules\",\"relative_path\":\".\",\"links\":\"follow\",\"owner\":0,\"group\":0,\"mode\":493,\"checksum\":{\"type\":\"ctime\",\"value\":\"{ctime}2020-03-06 20:14:25 UTC\"},\"type\":\"directory\",\"destination\":null}]" }
11
+
12
+ it "downloads from plugins, pluginsfacts and locales mounts" do
13
+ current_version_handler = -> (req, res) {
14
+ res['X-Puppet-Version'] = Puppet.version
15
+ res['Content-Type'] = 'application/json'
16
+ res.body = response_body
17
+ }
18
+
19
+ server.start_server(mounts: {file_metadatas: current_version_handler}) do |port|
20
+ Puppet[:masterport] = port
21
+ expect {
22
+ plugin.command_line.args << 'download'
23
+ plugin.run
24
+ }.to exit_with(0)
25
+ .and output(matching(
26
+ "Downloaded these plugins: #{Regexp.escape(Puppet[:pluginfactdest])}, #{Regexp.escape(Puppet[:plugindest])}, #{Regexp.escape(Puppet[:localedest])}"
27
+ )).to_stdout
28
+ end
29
+ end
30
+
31
+ it "downloads from plugins and pluginsfacts from older puppetservers" do
32
+ no_locales_handler = -> (req, res) {
33
+ res['X-Puppet-Version'] = '5.3.3' # locales mount was added in 5.3.4
34
+ res['Content-Type'] = 'application/json'
35
+ res.body = response_body
36
+ }
37
+
38
+ server.start_server(mounts: {file_metadatas: no_locales_handler}) do |port|
39
+ Puppet[:masterport] = port
40
+ expect {
41
+ plugin.command_line.args << 'download'
42
+ plugin.run
43
+ }.to exit_with(0)
44
+ .and output(matching(
45
+ "Downloaded these plugins: #{Regexp.escape(Puppet[:pluginfactdest])}, #{Regexp.escape(Puppet[:plugindest])}"
46
+ )).to_stdout
47
+ end
48
+ end
49
+
50
+ end
@@ -4,31 +4,17 @@ require 'puppet_spec/files'
4
4
 
5
5
  describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
6
6
  include PuppetSpec::Files
7
+ include_context "https client"
7
8
 
8
- before :all do
9
- WebMock.disable!
10
- end
11
-
12
- after :all do
13
- WebMock.enable!
14
- end
15
-
16
- before :each do
17
- # make sure we don't take too long
18
- Puppet[:http_connect_timeout] = '5s'
19
- end
20
-
21
- let(:hostname) { '127.0.0.1' }
22
9
  let(:wrong_hostname) { 'localhost' }
23
- let(:server) { PuppetSpec::HTTPSServer.new }
24
10
  let(:client) { Puppet::HTTP::Client.new }
25
11
  let(:ssl_provider) { Puppet::SSL::SSLProvider.new }
26
- let(:root_context) { ssl_provider.create_root_context(cacerts: [server.ca_cert], crls: [server.ca_crl]) }
12
+ let(:root_context) { ssl_provider.create_root_context(cacerts: [https_server.ca_cert], crls: [https_server.ca_crl]) }
27
13
 
28
14
  context "when verifying an HTTPS server" do
29
15
  it "connects over SSL" do
30
- server.start_server do |port|
31
- res = client.get(URI("https://127.0.0.1:#{port}"), ssl_context: root_context)
16
+ https_server.start_server do |port|
17
+ res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: root_context})
32
18
  expect(res).to be_success
33
19
  end
34
20
  end
@@ -41,14 +27,14 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
41
27
  port = tcps.connect_address.ip_port
42
28
 
43
29
  expect {
44
- client.get(URI("https://127.0.0.1:#{port}"), ssl_context: root_context)
30
+ client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: root_context})
45
31
  }.to raise_error(Puppet::HTTP::ConnectionError, %r{^Request to https://127.0.0.1:#{port} timed out connect operation after .* seconds})
46
32
  end
47
33
 
48
34
  it "raises if the server's cert doesn't match the hostname we connected to" do
49
- server.start_server do |port|
35
+ https_server.start_server do |port|
50
36
  expect {
51
- client.get(URI("https://#{wrong_hostname}:#{port}"), ssl_context: root_context)
37
+ client.get(URI("https://#{wrong_hostname}:#{port}"), options: {ssl_context: root_context})
52
38
  }.to raise_error { |err|
53
39
  expect(err).to be_instance_of(Puppet::SSL::CertMismatchError)
54
40
  expect(err.message).to match(/Server hostname '#{wrong_hostname}' did not match server certificate; expected one of (.+)/)
@@ -63,9 +49,9 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
63
49
  wrong_ca = cert_fixture('netlock-arany-utf8.pem')
64
50
  alt_context = ssl_provider.create_root_context(cacerts: [wrong_ca], revocation: false)
65
51
 
66
- server.start_server do |port|
52
+ https_server.start_server do |port|
67
53
  expect {
68
- client.get(URI("https://127.0.0.1:#{port}"), ssl_context: alt_context)
54
+ client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: alt_context})
69
55
  }.to raise_error(Puppet::SSL::CertVerifyError,
70
56
  %r{certificate verify failed.* .self signed certificate in certificate chain for CN=Test CA.})
71
57
  end
@@ -73,8 +59,8 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
73
59
 
74
60
  it "prints TLS protocol and ciphersuite in debug" do
75
61
  Puppet[:log_level] = 'debug'
76
- server.start_server do |port|
77
- client.get(URI("https://127.0.0.1:#{port}"), ssl_context: root_context)
62
+ https_server.start_server do |port|
63
+ client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: root_context})
78
64
  # TLS version string can be TLSv1 or TLSv1.[1-3], but not TLSv1.0
79
65
  expect(@logs).to include(
80
66
  an_object_having_attributes(level: :debug, message: /Using TLSv1(\.[1-3])? with cipher .*/),
@@ -93,12 +79,12 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
93
79
 
94
80
  it "mutually authenticates the connection" do
95
81
  client_context = ssl_provider.create_context(
96
- cacerts: [server.ca_cert], crls: [server.ca_crl],
97
- client_cert: server.server_cert, private_key: server.server_key
82
+ cacerts: [https_server.ca_cert], crls: [https_server.ca_crl],
83
+ client_cert: https_server.server_cert, private_key: https_server.server_key
98
84
  )
99
85
 
100
- server.start_server(ctx_proc: ctx_proc) do |port|
101
- res = client.get(URI("https://127.0.0.1:#{port}"), ssl_context: client_context)
86
+ https_server.start_server(ctx_proc: ctx_proc) do |port|
87
+ res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: client_context})
102
88
  expect(res).to be_success
103
89
  end
104
90
  end
@@ -106,10 +92,10 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
106
92
 
107
93
  context "with a system trust store" do
108
94
  it "connects when the client trusts the server's CA" do
109
- system_context = ssl_provider.create_system_context(cacerts: [server.ca_cert])
95
+ system_context = ssl_provider.create_system_context(cacerts: [https_server.ca_cert])
110
96
 
111
- server.start_server do |port|
112
- res = client.get(URI("https://127.0.0.1:#{port}"), ssl_context: system_context)
97
+ https_server.start_server do |port|
98
+ res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: system_context})
113
99
  expect(res).to be_success
114
100
  end
115
101
  end
@@ -117,14 +103,14 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
117
103
  it "connects when the server's CA is in the system store" do
118
104
  # create a temp cacert bundle
119
105
  ssl_file = tmpfile('systemstore')
120
- File.write(ssl_file, server.ca_cert)
106
+ File.write(ssl_file, https_server.ca_cert)
121
107
 
122
108
  # override path to system cacert bundle, this must be done before
123
109
  # the SSLContext is created and the call to X509::Store.set_default_paths
124
110
  Puppet::Util.withenv("SSL_CERT_FILE" => ssl_file) do
125
111
  system_context = ssl_provider.create_system_context(cacerts: [])
126
- server.start_server do |port|
127
- res = client.get(URI("https://127.0.0.1:#{port}"), ssl_context: system_context)
112
+ https_server.start_server do |port|
113
+ res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: system_context})
128
114
  expect(res).to be_success
129
115
  end
130
116
  end
@@ -133,9 +119,9 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
133
119
  it "raises if the server's CA is not in the context or system store" do
134
120
  system_context = ssl_provider.create_system_context(cacerts: [cert_fixture('netlock-arany-utf8.pem')])
135
121
 
136
- server.start_server do |port|
122
+ https_server.start_server do |port|
137
123
  expect {
138
- client.get(URI("https://127.0.0.1:#{port}"), ssl_context: system_context)
124
+ client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: system_context})
139
125
  }.to raise_error(Puppet::SSL::CertVerifyError,
140
126
  %r{certificate verify failed.* .self signed certificate in certificate chain for CN=Test CA.})
141
127
  end
@@ -144,11 +130,19 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
144
130
 
145
131
  context 'persistent connections' do
146
132
  it "detects when the server has closed the connection and reconnects" do
147
- server.start_server do |port|
133
+ Puppet[:http_debug] = true
134
+
135
+ https_server.start_server do |port|
148
136
  uri = URI("https://127.0.0.1:#{port}")
137
+ kwargs = {headers: {'Content-Type' => 'text/plain'}, options: {ssl_context: root_context}}
149
138
 
150
- expect(client.get(uri, ssl_context: root_context)).to be_success
151
- expect(client.get(uri, ssl_context: root_context)).to be_success
139
+ expect {
140
+ expect(client.post(uri, '', **kwargs)).to be_success
141
+ # the server closes its connection after each request, so posting
142
+ # again will force ruby to detect that the remote side closed the
143
+ # connection, and reconnect
144
+ expect(client.post(uri, '', **kwargs)).to be_success
145
+ }.to output(/Conn close because of EOF/).to_stderr
152
146
  end
153
147
  end
154
148
  end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ require 'puppet/transaction/report'
4
+ require 'puppet/indirector/report/yaml'
5
+
6
+ describe Puppet::Transaction::Report::Yaml do
7
+ describe '#save' do
8
+ subject(:indirection) { described_class.indirection }
9
+
10
+ let(:request) { described_class.new }
11
+ let(:certname) { 'ziggy' }
12
+ let(:report) do
13
+ report = Puppet::Transaction::Report.new
14
+ report.host = certname
15
+ report
16
+ end
17
+ let(:file) { request.path(:me) }
18
+
19
+ before do
20
+ indirection.terminus_class = :yaml
21
+ end
22
+
23
+ it 'is saves a report' do
24
+ indirection.save(report)
25
+ end
26
+
27
+ it 'saves the instance of the report as YAML to disk' do
28
+ indirection.save(report)
29
+ content = Puppet::Util::Yaml.safe_load_file(
30
+ Puppet[:lastrunreport], [Puppet::Transaction::Report]
31
+ )
32
+ expect(content.host).to eq(certname)
33
+ end
34
+
35
+ it 'allows mode overwrite' do
36
+ Puppet.settings.setting(:lastrunreport).mode = '0644'
37
+ indirection.save(report)
38
+
39
+ if Puppet::Util::Platform.windows?
40
+ require 'puppet/util/windows/security'
41
+ mode = Puppet::Util::Windows::Security.get_mode(file)
42
+ else
43
+ mode = Puppet::FileSystem.stat(file).mode
44
+ end
45
+
46
+ expect(mode & 07777).to eq(0644)
47
+ end
48
+
49
+ context 'when mode is invalid' do
50
+ before do
51
+ Puppet.settings.setting(:lastrunreport).mode = '9999'
52
+ end
53
+
54
+ after do
55
+ Puppet.settings.setting(:lastrunreport).mode = '0644'
56
+ end
57
+
58
+ it 'raises Puppet::DevError ' do
59
+ expect{
60
+ indirection.save(report)
61
+ }.to raise_error(Puppet::DevError, "replace_file mode: 9999 is invalid")
62
+ end
63
+ end
64
+
65
+ context 'when repport is invalid' do
66
+ it 'logs error' do
67
+ expect(Puppet).to receive(:send_log).with(:err, /Could not save yaml ziggy: can't dump anonymous class/)
68
+
69
+ report.configuration_version = Class.new
70
+ indirection.save(report)
71
+ end
72
+ end
73
+
74
+ context 'when report cannot be saved' do
75
+ it 'raises Errno::EISDIR' do
76
+ FileUtils.mkdir_p(file)
77
+ expect {
78
+ indirection.save(report)
79
+ }.to raise_error(Errno::EISDIR, /last_run_report.yaml/)
80
+ end
81
+ end
82
+ end
83
+ end