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,201 @@
1
+ require 'spec_helper'
2
+ require 'puppet/http'
3
+
4
+ # Simple "external" client to make get & post requests. This is used
5
+ # to test the old HTTP API, such as requiring use_ssl and basic_auth
6
+ # to be passed as options.
7
+ class Puppet::HTTP::TestExternal
8
+ def initialize(host, port, options = {})
9
+ @host = host
10
+ @port = port
11
+ @options = options
12
+ @factory = Puppet::Network::HTTP::Factory.new
13
+ end
14
+
15
+ def get(path, headers = {}, options = {})
16
+ request = Net::HTTP::Get.new(path, headers)
17
+ do_request(request, options)
18
+ end
19
+
20
+ def post(path, data, headers = nil, options = {})
21
+ request = Net::HTTP::Post.new(path, headers)
22
+ do_request(request, options)
23
+ end
24
+
25
+ def do_request(request, options)
26
+ if options[:basic_auth]
27
+ request.basic_auth(options[:basic_auth][:user], options[:basic_auth][:password])
28
+ end
29
+
30
+ site = Puppet::Network::HTTP::Site.new(@options[:use_ssl] ? 'https' : 'http', @host, @port)
31
+ http = @factory.create_connection(site)
32
+ http.start
33
+ begin
34
+ http.request(request)
35
+ ensure
36
+ http.finish
37
+ end
38
+ end
39
+ end
40
+
41
+ describe Puppet::HTTP::ExternalClient do
42
+ let(:uri) { URI.parse('https://www.example.com') }
43
+ let(:http_client_class) { Puppet::HTTP::TestExternal }
44
+ let(:client) { described_class.new(http_client_class) }
45
+ let(:credentials) { ['user', 'pass'] }
46
+
47
+ context "for GET requests" do
48
+ it "stringifies keys and encodes values in the query" do
49
+ stub_request(:get, uri).with(query: "foo=bar%3Dbaz")
50
+
51
+ client.get(uri, params: {:foo => "bar=baz"})
52
+ end
53
+
54
+ it "fails if a user passes in an invalid param type" do
55
+ environment = Puppet::Node::Environment.create(:testing, [])
56
+
57
+ expect{client.get(uri, params: {environment: environment})}.to raise_error(Puppet::HTTP::SerializationError, /HTTP REST queries cannot handle values of type/)
58
+ end
59
+
60
+ it "returns the response" do
61
+ stub_request(:get, uri)
62
+
63
+ response = client.get(uri)
64
+ expect(response).to be_an_instance_of(Puppet::HTTP::Response)
65
+ expect(response).to be_success
66
+ expect(response.code).to eq(200)
67
+ end
68
+
69
+ it "returns the entire response body" do
70
+ stub_request(:get, uri).to_return(body: "abc")
71
+
72
+ expect(client.get(uri).body).to eq("abc")
73
+ end
74
+
75
+ it "streams the response body when a block is given" do
76
+ stub_request(:get, uri).to_return(body: "abc")
77
+
78
+ io = StringIO.new
79
+ client.get(uri) do |response|
80
+ response.read_body do |data|
81
+ io.write(data)
82
+ end
83
+ end
84
+
85
+ expect(io.string).to eq("abc")
86
+ end
87
+
88
+ context 'when connecting' do
89
+ it 'accepts an ssl context' do
90
+ stub_request(:get, uri).to_return(body: "abc")
91
+
92
+ other_context = Puppet::SSL::SSLContext.new
93
+
94
+ client.get(uri, options: {ssl_context: other_context})
95
+ end
96
+
97
+ it 'accepts include_system_store' do
98
+ stub_request(:get, uri).to_return(body: "abc")
99
+
100
+ client.get(uri, options: {include_system_store: true})
101
+ end
102
+ end
103
+ end
104
+
105
+ context "for POST requests" do
106
+ it "stringifies keys and encodes values in the query" do
107
+ stub_request(:post, "https://www.example.com").with(query: "foo=bar%3Dbaz")
108
+
109
+ client.post(uri, "", params: {:foo => "bar=baz"}, headers: {'Content-Type' => 'text/plain'})
110
+ end
111
+
112
+ it "returns the response" do
113
+ stub_request(:post, uri)
114
+
115
+ response = client.post(uri, "", headers: {'Content-Type' => 'text/plain'})
116
+ expect(response).to be_an_instance_of(Puppet::HTTP::Response)
117
+ expect(response).to be_success
118
+ expect(response.code).to eq(200)
119
+ end
120
+
121
+ it "sets content-type for the body" do
122
+ stub_request(:post, uri).with(headers: {"Content-Type" => "text/plain"})
123
+
124
+ client.post(uri, "hello", headers: {'Content-Type' => 'text/plain'})
125
+ end
126
+
127
+ it "streams the response body when a block is given" do
128
+ stub_request(:post, uri).to_return(body: "abc")
129
+
130
+ io = StringIO.new
131
+ client.post(uri, "", headers: {'Content-Type' => 'text/plain'}) do |response|
132
+ response.read_body do |data|
133
+ io.write(data)
134
+ end
135
+ end
136
+
137
+ expect(io.string).to eq("abc")
138
+ end
139
+
140
+ it 'raises an ArgumentError if `body` is missing' do
141
+ expect {
142
+ client.post(uri, nil, headers: {'Content-Type' => 'text/plain'})
143
+ }.to raise_error(ArgumentError, /'post' requires a string 'body' argument/)
144
+ end
145
+
146
+ context 'when connecting' do
147
+ it 'accepts an ssl context' do
148
+ stub_request(:post, uri)
149
+
150
+ other_context = Puppet::SSL::SSLContext.new
151
+
152
+ client.post(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {ssl_context: other_context})
153
+ end
154
+
155
+ it 'accepts include_system_store' do
156
+ stub_request(:post, uri)
157
+
158
+ client.post(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {include_system_store: true})
159
+ end
160
+ end
161
+ end
162
+
163
+ context "Basic Auth" do
164
+ it "submits credentials for GET requests" do
165
+ stub_request(:get, uri).with(basic_auth: credentials)
166
+
167
+ client.get(uri, options: {user: 'user', password: 'pass'})
168
+ end
169
+
170
+ it "submits credentials for POST requests" do
171
+ stub_request(:post, uri).with(basic_auth: credentials)
172
+
173
+ client.post(uri, "", options: {content_type: 'text/plain', user: 'user', password: 'pass'})
174
+ end
175
+
176
+ it "returns response containing access denied" do
177
+ stub_request(:get, uri).with(basic_auth: credentials).to_return(status: [403, "Ye Shall Not Pass"])
178
+
179
+ response = client.get(uri, options: {user: 'user', password: 'pass'})
180
+ expect(response.code).to eq(403)
181
+ expect(response.reason).to eq("Ye Shall Not Pass")
182
+ expect(response).to_not be_success
183
+ end
184
+
185
+ it 'omits basic auth if user is nil' do
186
+ stub_request(:get, uri).with do |req|
187
+ expect(req.headers).to_not include('Authorization')
188
+ end
189
+
190
+ client.get(uri, options: {user: nil, password: 'pass'})
191
+ end
192
+
193
+ it 'omits basic auth if password is nil' do
194
+ stub_request(:get, uri).with do |req|
195
+ expect(req.headers).to_not include('Authorization')
196
+ end
197
+
198
+ client.get(uri, options: {user: 'user', password: nil})
199
+ end
200
+ end
201
+ end
@@ -70,6 +70,26 @@ describe Puppet::HTTP::Resolver do
70
70
  expect(service).to be_an_instance_of(Puppet::HTTP::Service::Ca)
71
71
  expect(service.url.to_s).to eq("https://apple.example.com:8142/puppet-ca/v1")
72
72
  end
73
+
74
+ it 'resolves once per session' do
75
+ failed = stub_request(:get, "https://ca.example.com:8141/status/v1/simple/master").to_return(status: 503)
76
+ passed = stub_request(:get, "https://apple.example.com:8142/status/v1/simple/master").to_return(status: 200)
77
+
78
+ service = subject.resolve(session, :puppet)
79
+ expect(service).to be_a(Puppet::HTTP::Service::Compiler)
80
+ expect(service.url.to_s).to eq("https://apple.example.com:8142/puppet/v3")
81
+
82
+ service = subject.resolve(session, :fileserver)
83
+ expect(service).to be_a(Puppet::HTTP::Service::FileServer)
84
+ expect(service.url.to_s).to eq("https://apple.example.com:8142/puppet/v3")
85
+
86
+ service = subject.resolve(session, :report)
87
+ expect(service).to be_a(Puppet::HTTP::Service::Report)
88
+ expect(service.url.to_s).to eq("https://apple.example.com:8142/puppet/v3")
89
+
90
+ expect(failed).to have_been_requested
91
+ expect(passed).to have_been_requested
92
+ end
73
93
  end
74
94
 
75
95
  context 'when resolving using SRV' do
@@ -68,7 +68,15 @@ describe Puppet::HTTP::Service::Ca do
68
68
  it 'gets a certificate from the "certificate" endpoint' do
69
69
  stub_request(:get, url).to_return(body: pem)
70
70
 
71
- expect(subject.get_certificate('ca')).to eq(pem)
71
+ _, body = subject.get_certificate('ca')
72
+ expect(body).to eq(pem)
73
+ end
74
+
75
+ it 'returns the request response' do
76
+ stub_request(:get, url).to_return(body: pem)
77
+
78
+ resp, _ = subject.get_certificate('ca')
79
+ expect(resp).to be_a(Puppet::HTTP::Response)
72
80
  end
73
81
 
74
82
  it 'accepts text/plain responses' do
@@ -107,7 +115,15 @@ describe Puppet::HTTP::Service::Ca do
107
115
  it 'gets a CRL from "certificate_revocation_list" endpoint' do
108
116
  stub_request(:get, url).to_return(body: pem)
109
117
 
110
- expect(subject.get_certificate_revocation_list).to eq(pem)
118
+ _, body = subject.get_certificate_revocation_list
119
+ expect(body).to eq(pem)
120
+ end
121
+
122
+ it 'returns the request response' do
123
+ stub_request(:get, url).to_return(body: pem)
124
+
125
+ resp, _ = subject.get_certificate_revocation_list
126
+ expect(resp).to be_a(Puppet::HTTP::Response)
111
127
  end
112
128
 
113
129
  it 'accepts text/plain responses' do
@@ -161,6 +177,13 @@ describe Puppet::HTTP::Service::Ca do
161
177
  subject.put_certificate_request('infinity', request)
162
178
  end
163
179
 
180
+ it 'returns the request response' do
181
+ stub_request(:put, url).with(body: pem, headers: { 'Content-Type' => 'text/plain' })
182
+
183
+ resp = subject.put_certificate_request('infinity', request)
184
+ expect(resp).to be_a(Puppet::HTTP::Response)
185
+ end
186
+
164
187
  it 'raises response error if unsuccessful' do
165
188
  stub_request(:put, url).to_return(status: [400, 'Bad Request'])
166
189
 
@@ -136,11 +136,19 @@ describe Puppet::HTTP::Service::Compiler do
136
136
  stub_request(:post, uri)
137
137
  .to_return(**catalog_response)
138
138
 
139
- cat = subject.post_catalog(certname, environment: 'production', facts: facts)
139
+ _, cat = subject.post_catalog(certname, environment: 'production', facts: facts)
140
140
  expect(cat).to be_a(Puppet::Resource::Catalog)
141
141
  expect(cat.name).to eq(certname)
142
142
  end
143
143
 
144
+ it 'returns the request response' do
145
+ stub_request(:post, uri)
146
+ .to_return(**catalog_response)
147
+
148
+ resp, _ = subject.post_catalog(certname, environment: 'production', facts: facts)
149
+ expect(resp).to be_a(Puppet::HTTP::Response)
150
+ end
151
+
144
152
  it 'raises a response error if unsuccessful' do
145
153
  stub_request(:post, uri)
146
154
  .to_return(status: [500, "Server Error"])
@@ -246,11 +254,19 @@ describe Puppet::HTTP::Service::Compiler do
246
254
  stub_request(:get, uri)
247
255
  .to_return(**node_response)
248
256
 
249
- n = subject.get_node(certname, environment: 'production')
257
+ _, n = subject.get_node(certname, environment: 'production')
250
258
  expect(n).to be_a(Puppet::Node)
251
259
  expect(n.name).to eq(certname)
252
260
  end
253
261
 
262
+ it 'returns the request response' do
263
+ stub_request(:get, uri)
264
+ .to_return(**node_response)
265
+
266
+ resp, _ = subject.get_node(certname, environment: 'production')
267
+ expect(resp).to be_a(Puppet::HTTP::Response)
268
+ end
269
+
254
270
  it 'raises a response error if unsuccessful' do
255
271
  stub_request(:get, uri)
256
272
  .to_return(status: [500, "Server Error"])
@@ -299,11 +315,19 @@ describe Puppet::HTTP::Service::Compiler do
299
315
  stub_request(:get, uri)
300
316
  .to_return(**facts_response)
301
317
 
302
- n = subject.get_facts(certname, environment: 'production')
318
+ _, n = subject.get_facts(certname, environment: 'production')
303
319
  expect(n).to be_a(Puppet::Node::Facts)
304
320
  expect(n.name).to eq(certname)
305
321
  end
306
322
 
323
+ it 'returns the request response' do
324
+ stub_request(:get, uri)
325
+ .to_return(**facts_response)
326
+
327
+ resp, _ = subject.get_facts(certname, environment: 'production')
328
+ expect(resp).to be_a(Puppet::HTTP::Response)
329
+ end
330
+
307
331
  it 'raises a response error if unsuccessful' do
308
332
  stub_request(:get, uri)
309
333
  .to_return(status: [500, "Server Error"])
@@ -365,12 +389,12 @@ describe Puppet::HTTP::Service::Compiler do
365
389
  subject.put_facts(certname, environment: 'outerspace', facts: facts)
366
390
  end
367
391
 
368
- it 'returns true' do
392
+ it 'returns the request response' do
369
393
  # the REST API returns the filename, good grief
370
394
  stub_request(:put, uri)
371
395
  .to_return(status: 200, body: "/opt/puppetlabs/server/data/puppetserver/yaml/facts/#{certname}.yaml")
372
396
 
373
- expect(subject.put_facts(certname, environment: environment, facts: facts)).to eq(true)
397
+ expect(subject.put_facts(certname, environment: environment, facts: facts)).to be_a(Puppet::HTTP::Response)
374
398
  end
375
399
 
376
400
  it 'raises a response error if unsuccessful' do
@@ -410,11 +434,19 @@ describe Puppet::HTTP::Service::Compiler do
410
434
  stub_request(:get, uri)
411
435
  .to_return(**status_response)
412
436
 
413
- s = subject.get_status(certname)
437
+ _, s = subject.get_status(certname)
414
438
  expect(s).to be_a(Puppet::Status)
415
439
  expect(s.status).to eq("is_alive" => true)
416
440
  end
417
441
 
442
+ it 'returns the request response' do
443
+ stub_request(:get, uri)
444
+ .to_return(**status_response)
445
+
446
+ resp, _ = subject.get_status(certname)
447
+ expect(resp).to be_a(Puppet::HTTP::Response)
448
+ end
449
+
418
450
  it 'raises a response error if unsuccessful' do
419
451
  stub_request(:get, uri)
420
452
  .to_return(status: [500, "Server Error"])
@@ -446,4 +478,150 @@ describe Puppet::HTTP::Service::Compiler do
446
478
  }.to raise_error(Puppet::HTTP::SerializationError, /Failed to deserialize Puppet::Status from json/)
447
479
  end
448
480
  end
481
+
482
+ context 'filebucket' do
483
+ let(:filebucket_file) { Puppet::FileBucket::File.new('file to store') }
484
+ let(:formatter) { Puppet::Network::FormatHandler.format(:binary) }
485
+ let(:path) { "md5/4aabe1257043bd03ce4c3319c155bc55" }
486
+ let(:uri) { %r{/puppet/v3/file_bucket_file/#{path}} }
487
+
488
+ context 'when getting a file' do
489
+ let(:status_response) { { body: formatter.render(filebucket_file), headers: {'Content-Type' => 'application/octet-stream' }}}
490
+
491
+ it 'includes default HTTP headers' do
492
+ stub_request(:get, uri).with do |request|
493
+ expect(request.headers).to include({
494
+ 'X-Puppet-Version' => /./,
495
+ 'User-Agent' => /./,
496
+ 'Accept' => 'application/octet-stream'
497
+ })
498
+ expect(request.headers).to_not include('X-Puppet-Profiling')
499
+ end.to_return(**status_response)
500
+
501
+ subject.get_filebucket_file(path, environment: 'production')
502
+ end
503
+
504
+ it 'always the environment as a parameter' do
505
+ stub_request(:get, uri).with(query: hash_including('environment' => 'production')).to_return(**status_response)
506
+
507
+ subject.get_filebucket_file(path, environment: 'production')
508
+ end
509
+
510
+ {bucket_path: 'path', diff_with: '4aabe1257043bd0', list_all: 'true', fromdate: '20200404', todate: '20200404'}.each do |param, val|
511
+ it "includes #{param} as a parameter in the request if #{param} is set" do
512
+ stub_request(:get, uri).with(query: hash_including(param => val)).to_return(**status_response)
513
+
514
+ options = { param => val }
515
+ subject.get_filebucket_file(path, environment: 'production', **options)
516
+ end
517
+ end
518
+
519
+ it "doesn't include :diff_with as a query param if :bucket_path is nil" do
520
+ stub_request(:get, uri).with do |request|
521
+ expect(request.uri.query).not_to match(/diff_with/)
522
+ end.to_return(**status_response)
523
+
524
+ subject.get_filebucket_file(path, environment: 'production', diff_with: nil)
525
+ end
526
+
527
+ it 'returns a deserialized response' do
528
+ stub_request(:get, uri)
529
+ .to_return(**status_response)
530
+
531
+ _, s = subject.get_filebucket_file(path, environment: 'production')
532
+ expect(s).to be_a(Puppet::FileBucket::File)
533
+ expect(s.contents).to eq('file to store')
534
+ end
535
+
536
+ it 'returns the request response' do
537
+ stub_request(:get, uri)
538
+ .to_return(**status_response)
539
+
540
+ resp, _ = subject.get_filebucket_file(path, environment: 'production')
541
+ expect(resp).to be_a(Puppet::HTTP::Response)
542
+ end
543
+ end
544
+
545
+ context 'when putting a file' do
546
+ let(:status_response) { { status: 200, body: '' } }
547
+
548
+ it 'includes default HTTP headers' do
549
+ stub_request(:put, uri).with do |request|
550
+ expect(request.headers).to include({
551
+ 'X-Puppet-Version' => /./,
552
+ 'User-Agent' => /./,
553
+ 'Accept' => 'application/octet-stream',
554
+ 'Content-Type' => 'application/octet-stream'
555
+ })
556
+ expect(request.headers).to_not include('X-Puppet-Profiling')
557
+ end.to_return(**status_response)
558
+
559
+ subject.put_filebucket_file(path, body: filebucket_file.contents, environment: 'production')
560
+ end
561
+
562
+ it 'always the environment as a parameter' do
563
+ stub_request(:put, uri).with(query: hash_including('environment' => 'production')).to_return(**status_response)
564
+
565
+ subject.put_filebucket_file(path, body: filebucket_file.contents, environment: 'production')
566
+ end
567
+
568
+ it 'sends the file contents as the request body' do
569
+ stub_request(:put, uri).with(body: filebucket_file.contents).to_return(**status_response)
570
+
571
+ subject.put_filebucket_file(path, body: filebucket_file.contents, environment: 'production')
572
+ end
573
+
574
+ it 'returns the request response' do
575
+ stub_request(:put, uri)
576
+ .to_return(**status_response)
577
+
578
+ s = subject.put_filebucket_file(path, body: filebucket_file.contents, environment: 'production')
579
+ expect(s).to be_a(Puppet::HTTP::Response)
580
+ end
581
+ end
582
+
583
+ context 'when heading a file' do
584
+ let(:status_response) {{ status: 200 }}
585
+
586
+ it 'includes default HTTP headers' do
587
+ stub_request(:head, uri).with do |request|
588
+ expect(request.headers).to include({
589
+ 'X-Puppet-Version' => /./,
590
+ 'User-Agent' => /./,
591
+ 'Accept' => 'application/octet-stream',
592
+ })
593
+ expect(request.headers).to_not include('X-Puppet-Profiling')
594
+ end.to_return(**status_response)
595
+
596
+ subject.head_filebucket_file(path, environment: 'production')
597
+ end
598
+
599
+ it 'always the environment as a parameter' do
600
+ stub_request(:head, uri).with(query: hash_including('environment' => 'production')).to_return(**status_response)
601
+
602
+ subject.head_filebucket_file(path, environment: 'production')
603
+ end
604
+
605
+ it "includes :bucket_path as a parameter in the request if :bucket_path is set" do
606
+ stub_request(:head, uri).with(query: hash_including(:bucket_path => 'some/path')).to_return(**status_response)
607
+
608
+ subject.head_filebucket_file(path, environment: 'production', bucket_path: 'some/path')
609
+ end
610
+
611
+ it "doesn't include :bucket_path as a query param if :bucket_path is nil" do
612
+ stub_request(:head, uri).with do |request|
613
+ expect(request.uri.query).not_to match(/bucket_path/)
614
+ end.to_return(**status_response)
615
+
616
+ subject.head_filebucket_file(path, environment: 'production', bucket_path: nil)
617
+ end
618
+
619
+ it "returns the request response" do
620
+ stub_request(:head, uri).with(query: hash_including(:bucket_path => 'some/path')).to_return(**status_response)
621
+
622
+ resp = subject.head_filebucket_file(path, environment: 'production', bucket_path: 'some/path')
623
+ expect(resp).to be_a(Puppet::HTTP::Response)
624
+ end
625
+ end
626
+ end
449
627
  end