puppet 6.4.5-x86-mingw32 → 6.5.0-x86-mingw32

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 (329) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +10 -10
  3. data/Gemfile +6 -6
  4. data/Gemfile.lock +46 -52
  5. data/ext/build_defaults.yaml +0 -1
  6. data/ext/project_data.yaml +3 -3
  7. data/ext/regexp_nodes/regexp_nodes.rb +4 -4
  8. data/ext/solaris/smf/puppet.xml +0 -2
  9. data/ext/windows/eventlog/Rakefile +32 -0
  10. data/ext/windows/eventlog/puppetres.dll +0 -0
  11. data/ext/windows/eventlog/puppetres.mc +18 -0
  12. data/ext/windows/service/daemon.rb +8 -38
  13. data/install.rb +24 -6
  14. data/lib/puppet.rb +3 -1
  15. data/lib/puppet/application.rb +1 -1
  16. data/lib/puppet/application/agent.rb +11 -34
  17. data/lib/puppet/application/apply.rb +6 -6
  18. data/lib/puppet/application/describe.rb +9 -3
  19. data/lib/puppet/application/device.rb +4 -14
  20. data/lib/puppet/application/doc.rb +1 -1
  21. data/lib/puppet/application/lookup.rb +2 -2
  22. data/lib/puppet/application/resource.rb +4 -4
  23. data/lib/puppet/application/script.rb +2 -2
  24. data/lib/puppet/application/ssl.rb +10 -9
  25. data/lib/puppet/configurer.rb +30 -86
  26. data/lib/puppet/configurer/downloader.rb +6 -2
  27. data/lib/puppet/defaults.rb +50 -44
  28. data/lib/puppet/error.rb +14 -9
  29. data/lib/puppet/face/catalog.rb +20 -1
  30. data/lib/puppet/face/config.rb +48 -10
  31. data/lib/puppet/face/facts.rb +1 -1
  32. data/lib/puppet/face/help.rb +1 -1
  33. data/lib/puppet/face/module/list.rb +5 -5
  34. data/lib/puppet/face/module/search.rb +1 -1
  35. data/lib/puppet/face/module/uninstall.rb +1 -1
  36. data/lib/puppet/face/module/upgrade.rb +1 -1
  37. data/lib/puppet/face/parser.rb +48 -9
  38. data/lib/puppet/face/plugin.rb +2 -9
  39. data/lib/puppet/file_serving/http_metadata.rb +1 -1
  40. data/lib/puppet/file_system.rb +12 -2
  41. data/lib/puppet/file_system/file_impl.rb +6 -3
  42. data/lib/puppet/file_system/memory_file.rb +1 -1
  43. data/lib/puppet/file_system/posix.rb +2 -3
  44. data/lib/puppet/forge.rb +3 -3
  45. data/lib/puppet/functions.rb +2 -1
  46. data/lib/puppet/functions/camelcase.rb +2 -2
  47. data/lib/puppet/functions/epp.rb +4 -4
  48. data/lib/puppet/functions/find_file.rb +9 -9
  49. data/lib/puppet/functions/inline_epp.rb +5 -5
  50. data/lib/puppet/functions/regsubst.rb +6 -8
  51. data/lib/puppet/gettext/module_translations.rb +1 -1
  52. data/lib/puppet/graph/rb_tree_map.rb +2 -2
  53. data/lib/puppet/graph/simple_graph.rb +3 -4
  54. data/lib/puppet/indirector/catalog/compiler.rb +5 -11
  55. data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
  56. data/lib/puppet/indirector/hiera.rb +0 -2
  57. data/lib/puppet/indirector/resource/ral.rb +3 -1
  58. data/lib/puppet/indirector/resource/validator.rb +1 -1
  59. data/lib/puppet/interface.rb +1 -2
  60. data/lib/puppet/loaders.rb +1 -0
  61. data/lib/puppet/metatype/manager.rb +1 -1
  62. data/lib/puppet/module.rb +1 -1
  63. data/lib/puppet/module/task.rb +4 -20
  64. data/lib/puppet/module_tool/applications/installer.rb +1 -1
  65. data/lib/puppet/module_tool/applications/uninstaller.rb +3 -3
  66. data/lib/puppet/module_tool/metadata.rb +1 -1
  67. data/lib/puppet/module_tool/shared_behaviors.rb +4 -4
  68. data/lib/puppet/module_tool/tar/mini.rb +2 -12
  69. data/lib/puppet/network/http/api/indirected_routes.rb +11 -12
  70. data/lib/puppet/network/http/connection.rb +12 -10
  71. data/lib/puppet/network/http/factory.rb +11 -1
  72. data/lib/puppet/network/http/pool.rb +0 -2
  73. data/lib/puppet/network/http/site.rb +1 -1
  74. data/lib/puppet/network/resolver.rb +2 -2
  75. data/lib/puppet/node/environment.rb +2 -4
  76. data/lib/puppet/pal/pal_impl.rb +2 -2
  77. data/lib/puppet/parser/ast.rb +1 -1
  78. data/lib/puppet/parser/ast/resourceparam.rb +1 -1
  79. data/lib/puppet/parser/functions.rb +1 -1
  80. data/lib/puppet/parser/functions/epp.rb +3 -3
  81. data/lib/puppet/parser/functions/fail.rb +8 -1
  82. data/lib/puppet/parser/functions/inline_epp.rb +5 -5
  83. data/lib/puppet/parser/scope.rb +7 -8
  84. data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +1 -1
  85. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +1 -1
  86. data/lib/puppet/pops/evaluator/external_syntax_support.rb +2 -3
  87. data/lib/puppet/pops/evaluator/runtime3_support.rb +4 -4
  88. data/lib/puppet/pops/loader/null_loader.rb +60 -0
  89. data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +6 -4
  90. data/lib/puppet/pops/loader/task_instantiator.rb +0 -4
  91. data/lib/puppet/pops/loaders.rb +1 -1
  92. data/lib/puppet/pops/lookup/hiera_config.rb +0 -1
  93. data/lib/puppet/pops/lookup/sub_lookup.rb +1 -1
  94. data/lib/puppet/pops/merge_strategy.rb +18 -22
  95. data/lib/puppet/pops/parser/heredoc_support.rb +1 -1
  96. data/lib/puppet/pops/parser/interpolation_support.rb +4 -4
  97. data/lib/puppet/pops/parser/locator.rb +1 -1
  98. data/lib/puppet/pops/parser/pn_parser.rb +16 -17
  99. data/lib/puppet/pops/puppet_stack.rb +49 -51
  100. data/lib/puppet/pops/types/p_sensitive_type.rb +1 -1
  101. data/lib/puppet/pops/types/string_converter.rb +10 -10
  102. data/lib/puppet/pops/types/types.rb +6 -5
  103. data/lib/puppet/property.rb +1 -1
  104. data/lib/puppet/property/ensure.rb +1 -1
  105. data/lib/puppet/provider/exec.rb +2 -6
  106. data/lib/puppet/provider/file/posix.rb +0 -5
  107. data/lib/puppet/provider/nameservice.rb +3 -10
  108. data/lib/puppet/provider/nameservice/directoryservice.rb +1 -1
  109. data/lib/puppet/provider/nameservice/pw.rb +2 -2
  110. data/lib/puppet/provider/package.rb +0 -2
  111. data/lib/puppet/provider/package/apt.rb +1 -5
  112. data/lib/puppet/provider/package/dnf.rb +1 -1
  113. data/lib/puppet/provider/package/dpkg.rb +18 -34
  114. data/lib/puppet/provider/package/openbsd.rb +1 -1
  115. data/lib/puppet/provider/package/pip.rb +13 -37
  116. data/lib/puppet/provider/package/portage.rb +4 -4
  117. data/lib/puppet/provider/package/puppet_gem.rb +1 -1
  118. data/lib/puppet/provider/package/rpm.rb +18 -56
  119. data/lib/puppet/provider/package/windows/package.rb +1 -1
  120. data/lib/puppet/provider/package/yum.rb +5 -9
  121. data/lib/puppet/provider/package_targetable.rb +4 -7
  122. data/lib/puppet/provider/parsedfile.rb +1 -1
  123. data/lib/puppet/provider/service/daemontools.rb +9 -9
  124. data/lib/puppet/provider/service/launchd.rb +5 -20
  125. data/lib/puppet/provider/service/openbsd.rb +1 -1
  126. data/lib/puppet/provider/service/rcng.rb +2 -2
  127. data/lib/puppet/provider/service/runit.rb +8 -2
  128. data/lib/puppet/provider/service/systemd.rb +19 -14
  129. data/lib/puppet/provider/service/windows.rb +0 -8
  130. data/lib/puppet/provider/user/directoryservice.rb +1 -1
  131. data/lib/puppet/provider/user/hpux.rb +1 -1
  132. data/lib/puppet/provider/user/pw.rb +3 -12
  133. data/lib/puppet/provider/user/user_role_add.rb +1 -5
  134. data/lib/puppet/provider/user/useradd.rb +20 -45
  135. data/lib/puppet/provider/user/windows_adsi.rb +5 -4
  136. data/lib/puppet/reference/configuration.rb +3 -3
  137. data/lib/puppet/reference/indirection.rb +2 -2
  138. data/lib/puppet/reference/metaparameter.rb +3 -1
  139. data/lib/puppet/reference/providers.rb +3 -1
  140. data/lib/puppet/reference/type.rb +9 -3
  141. data/lib/puppet/reports.rb +1 -1
  142. data/lib/puppet/resource.rb +1 -18
  143. data/lib/puppet/resource/catalog.rb +1 -1
  144. data/lib/puppet/rest/routes.rb +30 -17
  145. data/lib/puppet/settings.rb +3 -43
  146. data/lib/puppet/settings/environment_conf.rb +0 -1
  147. data/lib/puppet/ssl/certificate_request.rb +12 -2
  148. data/lib/puppet/ssl/host.rb +2 -2
  149. data/lib/puppet/ssl/oids.rb +1 -1
  150. data/lib/puppet/ssl/ssl_provider.rb +11 -5
  151. data/lib/puppet/ssl/state_machine.rb +102 -98
  152. data/lib/puppet/test/test_helper.rb +1 -0
  153. data/lib/puppet/transaction.rb +11 -33
  154. data/lib/puppet/transaction/report.rb +1 -1
  155. data/lib/puppet/type.rb +4 -2
  156. data/lib/puppet/type/exec.rb +17 -23
  157. data/lib/puppet/type/file.rb +39 -11
  158. data/lib/puppet/type/file/data_sync.rb +1 -5
  159. data/lib/puppet/type/group.rb +2 -4
  160. data/lib/puppet/type/notify.rb +3 -4
  161. data/lib/puppet/type/package.rb +3 -20
  162. data/lib/puppet/type/schedule.rb +1 -1
  163. data/lib/puppet/type/service.rb +3 -8
  164. data/lib/puppet/type/user.rb +2 -4
  165. data/lib/puppet/util.rb +29 -39
  166. data/lib/puppet/util/command_line/trollop.rb +1 -1
  167. data/lib/puppet/util/execution.rb +3 -4
  168. data/lib/puppet/util/http_proxy.rb +19 -27
  169. data/lib/puppet/util/log.rb +2 -2
  170. data/lib/puppet/util/log/destinations.rb +2 -2
  171. data/lib/puppet/util/logging.rb +20 -32
  172. data/lib/puppet/util/metric.rb +2 -2
  173. data/lib/puppet/util/monkey_patches.rb +33 -0
  174. data/lib/puppet/util/pidlock.rb +2 -3
  175. data/lib/puppet/util/provider_features.rb +4 -2
  176. data/lib/puppet/util/rdoc.rb +1 -1
  177. data/lib/puppet/util/reference.rb +1 -1
  178. data/lib/puppet/util/resource_template.rb +1 -1
  179. data/lib/puppet/util/selinux.rb +2 -8
  180. data/lib/puppet/util/skip_tags.rb +4 -0
  181. data/lib/puppet/util/windows/adsi.rb +18 -48
  182. data/lib/puppet/util/windows/process.rb +8 -8
  183. data/lib/puppet/util/windows/registry.rb +5 -7
  184. data/lib/puppet/util/windows/security.rb +0 -2
  185. data/lib/puppet/util/windows/service.rb +4 -149
  186. data/lib/puppet/util/windows/sid.rb +0 -1
  187. data/lib/puppet/vendor.rb +1 -1
  188. data/lib/puppet/version.rb +1 -1
  189. data/lib/puppet/x509/cert_provider.rb +81 -24
  190. data/locales/puppet.pot +462 -482
  191. data/man/man5/puppet.conf.5 +43 -44
  192. data/man/man8/puppet-agent.8 +1 -1
  193. data/man/man8/puppet-apply.8 +3 -3
  194. data/man/man8/puppet-catalog.8 +31 -3
  195. data/man/man8/puppet-config.8 +1 -1
  196. data/man/man8/puppet-describe.8 +1 -1
  197. data/man/man8/puppet-device.8 +1 -1
  198. data/man/man8/puppet-doc.8 +1 -1
  199. data/man/man8/puppet-epp.8 +1 -1
  200. data/man/man8/puppet-facts.8 +1 -1
  201. data/man/man8/puppet-filebucket.8 +1 -1
  202. data/man/man8/puppet-generate.8 +1 -1
  203. data/man/man8/puppet-help.8 +1 -1
  204. data/man/man8/puppet-key.8 +1 -1
  205. data/man/man8/puppet-lookup.8 +1 -1
  206. data/man/man8/puppet-man.8 +1 -1
  207. data/man/man8/puppet-module.8 +1 -1
  208. data/man/man8/puppet-node.8 +1 -1
  209. data/man/man8/puppet-parser.8 +1 -1
  210. data/man/man8/puppet-plugin.8 +1 -1
  211. data/man/man8/puppet-report.8 +1 -1
  212. data/man/man8/puppet-resource.8 +1 -1
  213. data/man/man8/puppet-script.8 +1 -1
  214. data/man/man8/puppet-ssl.8 +1 -1
  215. data/man/man8/puppet-status.8 +1 -1
  216. data/man/man8/puppet.8 +3 -3
  217. data/spec/fixtures/ssl/127.0.0.1-key.pem +56 -56
  218. data/spec/fixtures/ssl/127.0.0.1.pem +27 -27
  219. data/spec/fixtures/ssl/bad-basic-constraints.pem +32 -32
  220. data/spec/fixtures/ssl/bad-int-basic-constraints.pem +30 -30
  221. data/spec/fixtures/ssl/ca.pem +30 -30
  222. data/spec/fixtures/ssl/crl.pem +15 -15
  223. data/spec/fixtures/ssl/ec-key.pem +18 -0
  224. data/spec/fixtures/ssl/ec.pem +40 -0
  225. data/spec/fixtures/ssl/encrypted-ec-key.pem +21 -0
  226. data/spec/fixtures/ssl/encrypted-key.pem +57 -57
  227. data/spec/fixtures/ssl/intermediate-agent-crl.pem +16 -16
  228. data/spec/fixtures/ssl/intermediate-agent.pem +33 -33
  229. data/spec/fixtures/ssl/intermediate-crl.pem +17 -17
  230. data/spec/fixtures/ssl/intermediate.pem +31 -31
  231. data/spec/fixtures/ssl/pluto-key.pem +56 -56
  232. data/spec/fixtures/ssl/pluto.pem +28 -28
  233. data/spec/fixtures/ssl/request-key.pem +56 -56
  234. data/spec/fixtures/ssl/request.pem +24 -24
  235. data/spec/fixtures/ssl/revoked-key.pem +56 -56
  236. data/spec/fixtures/ssl/revoked.pem +25 -25
  237. data/spec/fixtures/ssl/signed-key.pem +56 -56
  238. data/spec/fixtures/ssl/signed.pem +25 -25
  239. data/spec/fixtures/ssl/tampered-cert.pem +27 -27
  240. data/spec/fixtures/ssl/tampered-csr.pem +24 -24
  241. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/usee/lib/puppet/parser/functions/func_with_syntax_error.rb +9 -0
  242. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_get/should_yield_to_the_block.yml +24 -0
  243. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_head/should_yield_to_the_block.yml +24 -0
  244. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_post/should_yield_to_the_block.yml +24 -0
  245. data/spec/integration/configurer_spec.rb +0 -52
  246. data/spec/integration/provider/service/init_spec.rb +1 -0
  247. data/spec/integration/provider/service/systemd_spec.rb +5 -8
  248. data/spec/integration/type/file_spec.rb +38 -28
  249. data/spec/integration/util/execution_spec.rb +0 -27
  250. data/spec/lib/puppet/certificate_factory.rb +2 -2
  251. data/spec/lib/puppet/test_ca.rb +17 -4
  252. data/spec/lib/puppet_spec/fixtures.rb +4 -0
  253. data/spec/spec_helper.rb +0 -28
  254. data/spec/unit/application/agent_spec.rb +34 -67
  255. data/spec/unit/application/device_spec.rb +1 -27
  256. data/spec/unit/application/ssl_spec.rb +60 -35
  257. data/spec/unit/configurer_spec.rb +399 -395
  258. data/spec/unit/defaults_spec.rb +4 -4
  259. data/spec/unit/face/facts_spec.rb +0 -9
  260. data/spec/unit/face/parser_spec.rb +69 -22
  261. data/spec/unit/face/plugin_spec.rb +0 -8
  262. data/spec/unit/file_system_spec.rb +30 -1
  263. data/spec/unit/forge/forge_spec.rb +3 -1
  264. data/spec/unit/forge/repository_spec.rb +3 -1
  265. data/spec/unit/indirector/catalog/compiler_spec.rb +5 -62
  266. data/spec/unit/indirector/resource/ral_spec.rb +4 -4
  267. data/spec/unit/module_tool/tar/mini_spec.rb +1 -1
  268. data/spec/unit/network/http/api/indirected_routes_spec.rb +10 -25
  269. data/spec/unit/network/http/connection_spec.rb +145 -119
  270. data/spec/unit/network/http/factory_spec.rb +5 -27
  271. data/spec/unit/parser/scope_spec.rb +0 -10
  272. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +3 -8
  273. data/spec/unit/pops/loaders/loaders_spec.rb +4 -0
  274. data/spec/unit/pops/loaders/module_loaders_spec.rb +0 -37
  275. data/spec/unit/pops/types/types_spec.rb +27 -0
  276. data/spec/unit/provider/exec_spec.rb +0 -209
  277. data/spec/unit/provider/package/aptrpm_spec.rb +1 -1
  278. data/spec/unit/provider/package/dnf_spec.rb +0 -7
  279. data/spec/unit/provider/package/dpkg_spec.rb +80 -240
  280. data/spec/unit/provider/package/pip_spec.rb +8 -61
  281. data/spec/unit/provider/package/portage_spec.rb +4 -4
  282. data/spec/unit/provider/package/rpm_spec.rb +16 -150
  283. data/spec/unit/provider/package/yum_spec.rb +0 -7
  284. data/spec/unit/provider/service/daemontools_spec.rb +0 -24
  285. data/spec/unit/provider/service/launchd_spec.rb +0 -28
  286. data/spec/unit/provider/service/runit_spec.rb +0 -24
  287. data/spec/unit/provider/service/systemd_spec.rb +25 -39
  288. data/spec/unit/provider/service/windows_spec.rb +0 -20
  289. data/spec/unit/provider/user/hpux_spec.rb +2 -2
  290. data/spec/unit/provider/user/pw_spec.rb +0 -37
  291. data/spec/unit/provider/user/useradd_spec.rb +0 -88
  292. data/spec/unit/resource_spec.rb +1 -26
  293. data/spec/unit/ssl/host_spec.rb +5 -0
  294. data/spec/unit/ssl/ssl_provider_spec.rb +36 -11
  295. data/spec/unit/ssl/state_machine_spec.rb +233 -158
  296. data/spec/unit/transaction_spec.rb +0 -64
  297. data/spec/unit/type/exec_spec.rb +12 -15
  298. data/spec/unit/type/file/content_spec.rb +3 -9
  299. data/spec/unit/type/file/source_spec.rb +4 -4
  300. data/spec/unit/type/file_spec.rb +15 -11
  301. data/spec/unit/type/package_spec.rb +0 -5
  302. data/spec/unit/type/schedule_spec.rb +1 -3
  303. data/spec/unit/type/service_spec.rb +0 -16
  304. data/spec/unit/util/execution_spec.rb +0 -16
  305. data/spec/unit/util/http_proxy_spec.rb +21 -151
  306. data/spec/unit/util/ldap/manager_spec.rb +0 -15
  307. data/spec/unit/util/log/destinations_spec.rb +3 -7
  308. data/spec/unit/util/log_spec.rb +138 -0
  309. data/spec/unit/util/logging_spec.rb +0 -200
  310. data/spec/unit/util/pidlock_spec.rb +0 -26
  311. data/spec/unit/util/skip_tags_spec.rb +14 -0
  312. data/spec/unit/util/windows/adsi_spec.rb +0 -51
  313. data/spec/unit/util/windows/service_spec.rb +0 -9
  314. data/spec/unit/util_spec.rb +10 -0
  315. data/spec/unit/x509/cert_provider_spec.rb +82 -43
  316. data/tasks/generate_cert_fixtures.rake +13 -1
  317. data/tasks/manpages.rake +0 -1
  318. metadata +28 -22
  319. data/ext/cert_inspector +0 -140
  320. data/ext/envpuppet +0 -139
  321. data/ext/envpuppet.bat +0 -14
  322. data/ext/puppet-test +0 -476
  323. data/ext/pure_ruby_dsl/dsl_test.rb +0 -7
  324. data/ext/upload_facts.rb +0 -119
  325. data/lib/puppet/provider/package/dnfmodule.rb +0 -87
  326. data/spec/fixtures/unit/provider/package/dnfmodule/dnf-module-list-installed.txt +0 -11
  327. data/spec/integration/type/notify_spec.rb +0 -46
  328. data/spec/unit/provider/package/dnfmodule_spec.rb +0 -186
  329. data/spec/unit/provider/package_targetable_spec.rb +0 -60
@@ -370,19 +370,9 @@ describe Puppet::Application::Device do
370
370
  allow(configurer).to receive(:run)
371
371
  allow(Puppet::Configurer).to receive(:new).and_return(configurer)
372
372
 
373
- allow(Puppet::FileSystem).to receive(:exist?)
374
- allow(Puppet::FileSystem).to receive(:symlink)
375
- allow(Puppet::FileSystem).to receive(:dir_mkpath).and_return(true)
376
- allow(Puppet::FileSystem).to receive(:dir_exist?).and_return(true)
377
-
378
373
  allow(plugin_handler).to receive(:download_plugins)
379
374
  end
380
375
 
381
- it "sets ssldir relative to the global confdir" do
382
- expect(Puppet).to receive(:[]=).with(:ssldir, make_absolute("/dummy/devices/device1/ssl"))
383
- expect { device.main }.to exit_with 1
384
- end
385
-
386
376
  it "sets vardir to the device vardir" do
387
377
  expect(Puppet).to receive(:[]=).with(:vardir, make_absolute("/dummy/devices/device1"))
388
378
  expect { device.main }.to exit_with 1
@@ -400,22 +390,6 @@ describe Puppet::Application::Device do
400
390
  end
401
391
 
402
392
  context 'with --target=device1' do
403
- it "symlinks the ssl directory if it doesn't exist" do
404
- allow(device.options).to receive(:[]).with(:target).and_return('device1')
405
- allow(Puppet::FileSystem).to receive(:exist?).and_return(false)
406
-
407
- expect(Puppet::FileSystem).to receive(:symlink).with(Puppet[:ssldir], File.join(Puppet[:confdir], 'ssl')).and_return(true)
408
- expect { device.main }.to exit_with 1
409
- end
410
-
411
- it "creates the device confdir under the global confdir" do
412
- allow(device.options).to receive(:[]).with(:target).and_return('device1')
413
- allow(Puppet::FileSystem).to receive(:dir_exist?).and_return(false)
414
-
415
- expect(Puppet::FileSystem).to receive(:dir_mkpath).with(Puppet[:ssldir]).and_return(true)
416
- expect { device.main }.to exit_with 1
417
- end
418
-
419
393
  it "manages the specified target" do
420
394
  allow(device.options).to receive(:[]).with(:target).and_return('device1')
421
395
 
@@ -464,7 +438,7 @@ describe Puppet::Application::Device do
464
438
  allow(device.options).to receive(:[]).with(:to_yaml).and_return(true)
465
439
  allow(device.command_line).to receive(:args).and_return(['user'])
466
440
  expect(Puppet::Resource.indirection).to receive(:search).with('user/', {}).and_return(resources)
467
- expect(device).to receive(:puts).with("---\nuser:\n title: {}\n")
441
+ expect(device).to receive(:puts).with("user:\n title:\n")
468
442
  expect { device.main }.to exit_with 0
469
443
  end
470
444
  end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'puppet/application/ssl'
3
+ require 'webmock/rspec'
3
4
  require 'openssl'
4
5
  require 'puppet/test_ca'
5
6
 
@@ -22,17 +23,22 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
22
23
  end
23
24
 
24
25
  before do
26
+ WebMock.disable_net_connect!
27
+
28
+ allow_any_instance_of(Net::HTTP).to receive(:start)
29
+ allow_any_instance_of(Net::HTTP).to receive(:finish)
30
+
25
31
  Puppet.settings.use(:main)
26
32
  Puppet[:certname] = name
27
33
  Puppet[:vardir] = tmpdir("ssl_testing")
28
34
 
29
35
  # Host assumes ca cert and crl are present
30
- File.open(Puppet[:localcacert], 'w') { |f| f.write(@ca_cert.to_pem) }
31
- File.open(Puppet[:hostcrl], 'w') { |f| f.write(@crl.to_pem) }
36
+ File.write(Puppet[:localcacert], @ca_cert.to_pem)
37
+ File.write(Puppet[:hostcrl], @crl.to_pem)
32
38
 
33
39
  # Setup our ssl client
34
- File.open(Puppet[:hostprivkey], 'w') { |f| f.write(@host[:private_key].to_pem) }
35
- File.open(Puppet[:hostpubkey], 'w') { |f| f.write(@host[:private_key].public_key.to_pem) }
40
+ File.write(Puppet[:hostprivkey], @host[:private_key].to_pem)
41
+ File.write(Puppet[:hostpubkey], @host[:private_key].public_key.to_pem)
36
42
  end
37
43
 
38
44
  def expects_command_to_pass(expected_output = nil)
@@ -100,11 +106,22 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
100
106
 
101
107
  it_behaves_like 'an ssl action'
102
108
 
103
- it 'registers OIDs' do
109
+ it 'generates an RSA private key' do
110
+ File.unlink(Puppet[:hostprivkey])
111
+
112
+ stub_request(:put, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 200)
113
+ stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 404)
114
+
115
+ expects_command_to_pass(%r{Submitted certificate request for '#{name}' to https://.*})
116
+ end
117
+
118
+ it 'generates an EC private key' do
119
+ Puppet[:key_type] = 'ec'
120
+ File.unlink(Puppet[:hostprivkey])
121
+
104
122
  stub_request(:put, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 200)
105
123
  stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 404)
106
124
 
107
- expect(Puppet::SSL::Oids).to receive(:register_puppet_oids)
108
125
  expects_command_to_pass(%r{Submitted certificate request for '#{name}' to https://.*})
109
126
  end
110
127
 
@@ -168,7 +185,7 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
168
185
  end
169
186
 
170
187
  it 'overwrites an existing cert' do
171
- File.open(Puppet[:hostcert], 'w') { |f| f.write "existing certificate" }
188
+ File.write(Puppet[:hostcert], "existing certificate")
172
189
 
173
190
  stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 200, body: @host[:cert].to_pem)
174
191
 
@@ -178,12 +195,12 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
178
195
  end
179
196
 
180
197
  it "reports an error if the downloaded cert's public key doesn't match our private key" do
181
- File.open(Puppet[:hostcert], 'w') { |f| f.write "existing cert" }
198
+ File.write(Puppet[:hostcert], "existing cert")
182
199
 
183
200
  # generate a new host key, whose public key doesn't match the cert
184
201
  private_key = OpenSSL::PKey::RSA.new(512)
185
- File.open(Puppet[:hostprivkey], 'w') { |f| f.write(private_key.to_pem) }
186
- File.open(Puppet[:hostpubkey], 'w') { |f| f.write(private_key.public_key.to_pem) }
202
+ File.write(Puppet[:hostprivkey], private_key.to_pem)
203
+ File.write(Puppet[:hostpubkey], private_key.public_key.to_pem)
187
204
 
188
205
  stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 200, body: @host[:cert].to_pem)
189
206
 
@@ -203,7 +220,7 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
203
220
  before do
204
221
  ssl.command_line.args << 'verify'
205
222
 
206
- File.open(Puppet[:hostcert], 'w') { |f| f.write(@host[:cert].to_pem) }
223
+ File.write(Puppet[:hostcert], @host[:cert].to_pem)
207
224
  end
208
225
 
209
226
  it 'reports if the key is missing' do
@@ -222,8 +239,8 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
222
239
  # generate new keys
223
240
  private_key = OpenSSL::PKey::RSA.new(512)
224
241
  public_key = private_key.public_key
225
- File.open(Puppet[:hostprivkey], 'w') { |f| f.write(private_key.to_pem) }
226
- File.open(Puppet[:hostpubkey], 'w') { |f| f.write(public_key.to_pem) }
242
+ File.write(Puppet[:hostprivkey], private_key.to_pem)
243
+ File.write(Puppet[:hostpubkey], public_key.to_pem)
227
244
 
228
245
  expects_command_to_fail(%r{The certificate for 'CN=ssl-client' does not match its private key})
229
246
  end
@@ -231,19 +248,35 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
231
248
  it 'reports if the cert verification fails' do
232
249
  # generate a new CA to force an error
233
250
  new_ca = Puppet::TestCa.new
234
- File.open(Puppet[:localcacert], 'w') { |f| f.write(new_ca.ca_cert.to_pem) }
251
+ File.write(Puppet[:localcacert], new_ca.ca_cert.to_pem)
235
252
 
236
253
  # and CRL for that CA
237
- File.open(Puppet[:hostcrl], 'w') { |f| f.write(new_ca.ca_crl.to_pem) }
254
+ File.write(Puppet[:hostcrl], new_ca.ca_crl.to_pem)
238
255
 
239
256
  expects_command_to_fail(%r{Invalid signature for certificate 'CN=ssl-client'})
240
257
  end
241
258
 
242
259
  it 'reports when verification succeeds' do
243
- allow_any_instance_of(OpenSSL::X509::Store).to receive(:verify).and_return(true)
244
-
245
260
  expects_command_to_pass(%r{Verified client certificate 'CN=ssl-client' fingerprint})
246
261
  end
262
+
263
+ it 'reports when verification succeeds with a password protected private key' do
264
+ FileUtils.cp(File.join(PuppetSpec::FIXTURE_DIR, 'ssl', 'encrypted-key.pem'), Puppet[:hostprivkey])
265
+ FileUtils.cp(File.join(PuppetSpec::FIXTURE_DIR, 'ssl', 'signed.pem'), Puppet[:hostcert])
266
+
267
+ Puppet[:passfile] = file_containing('passfile', '74695716c8b6')
268
+
269
+ expects_command_to_pass(%r{Verified client certificate 'CN=signed' fingerprint})
270
+ end
271
+
272
+ it 'reports if the private key password is incorrect' do
273
+ FileUtils.cp(File.join(PuppetSpec::FIXTURE_DIR, 'ssl', 'encrypted-key.pem'), Puppet[:hostprivkey])
274
+ FileUtils.cp(File.join(PuppetSpec::FIXTURE_DIR, 'ssl', 'signed.pem'), Puppet[:hostcert])
275
+
276
+ Puppet[:passfile] = file_containing('passfile', 'wrongpassword')
277
+
278
+ expects_command_to_fail(/Failed to load private key for host 'ssl-client'/)
279
+ end
247
280
  end
248
281
 
249
282
  context 'when cleaning' do
@@ -252,32 +285,32 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
252
285
  end
253
286
 
254
287
  it 'deletes the hostcert' do
255
- File.open(Puppet[:hostcert], 'w') { |f| f.write(@host[:cert].to_pem) }
288
+ File.write(Puppet[:hostcert], @host[:cert].to_pem)
256
289
 
257
290
  expects_command_to_pass(%r{Removed certificate #{Puppet[:cert]}})
258
291
  end
259
292
 
260
293
  it 'deletes the private key' do
261
- File.open(Puppet[:hostprivkey], 'w') { |f| f.write(@host[:private_key].to_pem) }
294
+ File.write(Puppet[:hostprivkey], @host[:private_key].to_pem)
262
295
 
263
296
  expects_command_to_pass(%r{Removed private key #{Puppet[:hostprivkey]}})
264
297
  end
265
298
 
266
299
  it 'deletes the public key' do
267
- File.open(Puppet[:hostpubkey], 'w') { |f| f.write(@host[:private_key].public_key.to_pem) }
300
+ File.write(Puppet[:hostpubkey], @host[:private_key].public_key.to_pem)
268
301
 
269
302
  expects_command_to_pass(%r{Removed public key #{Puppet[:hostpubkey]}})
270
303
  end
271
304
 
272
305
  it 'deletes the request' do
273
306
  path = File.join(Puppet[:requestdir], "#{Puppet[:certname]}.pem")
274
- File.open(path, 'w') { |f| f.write(@host[:csr].to_pem) }
307
+ File.write(path, @host[:csr].to_pem)
275
308
 
276
309
  expects_command_to_pass(%r{Removed certificate request #{path}})
277
310
  end
278
311
 
279
312
  it 'deletes the passfile' do
280
- File.open(Puppet[:passfile], 'w') { |_| }
313
+ FileUtils.touch(Puppet[:passfile])
281
314
 
282
315
  expects_command_to_pass(%r{Removed private key password file #{Puppet[:passfile]}})
283
316
  end
@@ -306,13 +339,13 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
306
339
  end
307
340
 
308
341
  it 'deletes the local CA cert' do
309
- File.open(Puppet[:localcacert], 'w') { |f| f.write(@ca_cert.to_pem) }
342
+ File.write(Puppet[:localcacert], @ca_cert.to_pem)
310
343
 
311
344
  expects_command_to_pass(%r{Removed local CA certificate #{Puppet[:localcacert]}})
312
345
  end
313
346
 
314
347
  it 'deletes the local CRL' do
315
- File.open(Puppet[:hostcrl], 'w') { |f| f.write(@crl.to_pem) }
348
+ File.write(Puppet[:hostcrl], @crl.to_pem)
316
349
 
317
350
  expects_command_to_pass(%r{Removed local CRL #{Puppet[:hostcrl]}})
318
351
  end
@@ -331,7 +364,7 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
331
364
  end
332
365
 
333
366
  it "cleans the cert when the CA is local and the CA has already cleaned its cert" do
334
- File.open(Puppet[:hostcert], 'w') { |f| f.write(@host[:cert].to_pem) }
367
+ File.write(Puppet[:hostcert], @host[:cert].to_pem)
335
368
 
336
369
  stub_request(:get, %r{puppet-ca/v1/certificate/puppetserver}).to_return(status: 404)
337
370
 
@@ -339,7 +372,7 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
339
372
  end
340
373
 
341
374
  it "cleans the cert when run on a puppetserver that isn't the CA" do
342
- File.open(Puppet[:hostcert], 'w') { |f| f.write(@host[:cert].to_pem) }
375
+ File.write(Puppet[:hostcert], @host[:cert].to_pem)
343
376
 
344
377
  Puppet[:ca_server] = 'caserver'
345
378
 
@@ -357,7 +390,7 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
357
390
  device_cert_path = File.join(Puppet[:devicedir], 'device.example.com', 'ssl', 'certs')
358
391
  device_cert_file = File.join(device_cert_path, 'device.example.com.pem')
359
392
  FileUtils.mkdir_p(device_cert_path)
360
- File.open(device_cert_file, 'w') { |f| f.write('device.example.com') }
393
+ File.write(device_cert_file, 'device.example.com')
361
394
  expects_command_to_pass(%r{Removed certificate #{device_cert_file}})
362
395
  end
363
396
  end
@@ -368,14 +401,6 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
368
401
  ssl.command_line.args << 'bootstrap'
369
402
  end
370
403
 
371
- it 'registers the OIDs' do
372
- expect_any_instance_of(Puppet::SSL::StateMachine).to receive(:ensure_client_certificate).and_return(
373
- double('ssl_context')
374
- )
375
- expect(Puppet::SSL::Oids).to receive(:register_puppet_oids)
376
- expects_command_to_pass
377
- end
378
-
379
404
  it 'returns an SSLContext with the loaded CA certs, CRLs, private key and client cert' do
380
405
  expect_any_instance_of(Puppet::SSL::StateMachine).to receive(:ensure_client_certificate).and_return(
381
406
  double('ssl_context')
@@ -1,90 +1,108 @@
1
1
  require 'spec_helper'
2
2
  require 'puppet/configurer'
3
- require 'webmock/rspec'
4
3
 
5
4
  describe Puppet::Configurer do
6
5
  before do
7
- Puppet::Node::Facts.indirection.terminus_class = :memory
8
- Puppet::Node::Facts.indirection.save(facts)
9
-
6
+ allow(Puppet.settings).to receive(:use).and_return(true)
7
+ @agent = Puppet::Configurer.new
8
+ allow(@agent).to receive(:init_storage)
9
+ allow(Puppet::Util::Storage).to receive(:store)
10
10
  Puppet[:server] = "puppetmaster"
11
11
  Puppet[:report] = true
12
-
13
- catalog.add_resource(resource)
14
12
  end
15
13
 
16
- let(:configurer) { Puppet::Configurer.new }
17
- let(:report) { Puppet::Transaction::Report.new }
18
- let(:catalog) { Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote(Puppet[:environment].to_sym)) }
19
- let(:resource) { Puppet::Resource.new(:notice, 'a') }
20
- let(:facts) { Puppet::Node::Facts.new(Puppet[:node_name_value]) }
14
+ it "should include the Fact Handler module" do
15
+ expect(Puppet::Configurer.ancestors).to be_include(Puppet::Configurer::FactHandler)
16
+ end
21
17
 
22
18
  describe "when executing a pre-run hook" do
23
19
  it "should do nothing if the hook is set to an empty string" do
24
20
  Puppet.settings[:prerun_command] = ""
25
- expect(Puppet::Util::Execution).not_to receive(:execute)
21
+ expect(Puppet::Util).not_to receive(:exec)
26
22
 
27
- configurer.execute_prerun_command
23
+ @agent.execute_prerun_command
28
24
  end
29
25
 
30
26
  it "should execute any pre-run command provided via the 'prerun_command' setting" do
31
27
  Puppet.settings[:prerun_command] = "/my/command"
32
28
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
33
29
 
34
- configurer.execute_prerun_command
30
+ @agent.execute_prerun_command
35
31
  end
36
32
 
37
33
  it "should fail if the command fails" do
38
34
  Puppet.settings[:prerun_command] = "/my/command"
39
35
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
40
36
 
41
- expect(configurer.execute_prerun_command).to be_falsey
37
+ expect(@agent.execute_prerun_command).to be_falsey
42
38
  end
43
39
  end
44
40
 
45
41
  describe "when executing a post-run hook" do
46
42
  it "should do nothing if the hook is set to an empty string" do
47
43
  Puppet.settings[:postrun_command] = ""
48
- expect(Puppet::Util::Execution).not_to receive(:execute)
44
+ expect(Puppet::Util).not_to receive(:exec)
49
45
 
50
- configurer.execute_postrun_command
46
+ @agent.execute_postrun_command
51
47
  end
52
48
 
53
49
  it "should execute any post-run command provided via the 'postrun_command' setting" do
54
50
  Puppet.settings[:postrun_command] = "/my/command"
55
51
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
56
52
 
57
- configurer.execute_postrun_command
53
+ @agent.execute_postrun_command
58
54
  end
59
55
 
60
56
  it "should fail if the command fails" do
61
57
  Puppet.settings[:postrun_command] = "/my/command"
62
58
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
63
59
 
64
- expect(configurer.execute_postrun_command).to be_falsey
60
+ expect(@agent.execute_postrun_command).to be_falsey
65
61
  end
66
62
  end
67
63
 
68
64
  describe "when executing a catalog run" do
69
65
  before do
66
+ allow(Puppet.settings).to receive(:use).and_return(true)
67
+ allow(@agent).to receive(:download_plugins)
68
+ Puppet::Node::Facts.indirection.terminus_class = :memory
69
+ @facts = Puppet::Node::Facts.new(Puppet[:node_name_value])
70
+ Puppet::Node::Facts.indirection.save(@facts)
71
+
72
+ @catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote(Puppet[:environment].to_sym))
73
+ allow(@catalog).to receive(:to_ral).and_return(@catalog)
70
74
  Puppet::Resource::Catalog.indirection.terminus_class = :rest
71
- allow(Puppet::Resource::Catalog.indirection).to receive(:find).and_return(catalog)
75
+ allow(Puppet::Resource::Catalog.indirection).to receive(:find).and_return(@catalog)
76
+ allow(@agent).to receive(:send_report)
77
+ allow(@agent).to receive(:save_last_run_summary)
78
+
79
+ allow(Puppet::Util::Log).to receive(:close_all)
80
+ end
81
+
82
+ after :all do
83
+ Puppet::Node::Facts.indirection.reset_terminus_class
84
+ Puppet::Resource::Catalog.indirection.reset_terminus_class
85
+ end
86
+
87
+ it "should initialize storage" do
88
+ expect(Puppet::Util::Storage).to receive(:load)
89
+ @agent.run
72
90
  end
73
91
 
74
92
  it "downloads plugins when told" do
75
- expect(configurer).to receive(:download_plugins)
76
- configurer.run(:pluginsync => true)
93
+ expect(@agent).to receive(:download_plugins)
94
+ @agent.run(:pluginsync => true)
77
95
  end
78
96
 
79
97
  it "does not download plugins when told" do
80
- expect(configurer).not_to receive(:download_plugins)
81
- configurer.run(:pluginsync => false)
98
+ expect(@agent).not_to receive(:download_plugins)
99
+ @agent.run(:pluginsync => false)
82
100
  end
83
101
 
84
102
  it "should carry on when it can't fetch its node definition" do
85
103
  error = Net::HTTPError.new(400, 'dummy server communication error')
86
104
  expect(Puppet::Node.indirection).to receive(:find).and_raise(error)
87
- expect(configurer.run).to eq(0)
105
+ expect(@agent.run).to eq(0)
88
106
  end
89
107
 
90
108
  it "applies a cached catalog when it can't connect to the master" do
@@ -92,157 +110,200 @@ describe Puppet::Configurer do
92
110
 
93
111
  expect(Puppet::Node.indirection).to receive(:find).and_raise(error)
94
112
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(:ignore_cache => true)).and_raise(error)
95
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(:ignore_terminus => true)).and_return(catalog)
113
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(:ignore_terminus => true)).and_return(@catalog)
96
114
 
97
- expect(configurer.run).to eq(0)
115
+ expect(@agent.run).to eq(0)
98
116
  end
99
117
 
100
118
  it "should initialize a transaction report if one is not provided" do
119
+ report = Puppet::Transaction::Report.new
101
120
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
102
121
 
103
- configurer.run
122
+ @agent.run
104
123
  end
105
124
 
106
125
  it "should respect node_name_fact when setting the host on a report" do
107
126
  Puppet[:node_name_fact] = 'my_name_fact'
108
- facts.values = {'my_name_fact' => 'node_name_from_fact'}
109
- Puppet::Node::Facts.indirection.save(facts)
127
+ @facts.values = {'my_name_fact' => 'node_name_from_fact'}
128
+
129
+ report = Puppet::Transaction::Report.new
110
130
 
111
- configurer.run(:report => report)
131
+ @agent.run(:report => report)
112
132
  expect(report.host).to eq('node_name_from_fact')
113
133
  end
114
134
 
115
- it "creates a new report when applying the catalog" do
116
- options = {}
117
- configurer.run(options)
135
+ it "should pass the new report to the catalog" do
136
+ report = Puppet::Transaction::Report.new
137
+ allow(Puppet::Transaction::Report).to receive(:new).and_return(report)
138
+ expect(@catalog).to receive(:apply).with(hash_including(report: report))
139
+
140
+ @agent.run
141
+ end
142
+
143
+ it "should use the provided report if it was passed one" do
144
+ report = Puppet::Transaction::Report.new
145
+ expect(@catalog).to receive(:apply).with(hash_including(report: report))
146
+
147
+ @agent.run(:report => report)
148
+ end
149
+
150
+ it "should set the report as a log destination" do
151
+ report = Puppet::Transaction::Report.new
152
+
153
+ expect(report).to receive(:<<).with(instance_of(Puppet::Util::Log)).at_least(:once)
118
154
 
119
- expect(options[:report].metrics['time']['catalog_application']).to be_an_instance_of(Float)
155
+ @agent.run(:report => report)
120
156
  end
121
157
 
122
- it "uses the provided report when applying the catalog" do
123
- configurer.run(:report => report)
158
+ it "should retrieve the catalog" do
159
+ expect(@agent).to receive(:retrieve_catalog)
124
160
 
125
- expect(report.metrics['time']['catalog_application']).to be_an_instance_of(Float)
161
+ @agent.run
126
162
  end
127
163
 
128
164
  it "should log a failure and do nothing if no catalog can be retrieved" do
129
- expect(configurer).to receive(:retrieve_catalog).and_return(nil)
165
+ expect(@agent).to receive(:retrieve_catalog).and_return(nil)
130
166
 
131
167
  expect(Puppet).to receive(:err).with("Could not retrieve catalog; skipping run")
132
168
 
133
- configurer.run
169
+ @agent.run
134
170
  end
135
171
 
136
- it "passes arbitrary options when applying the catalog" do
137
- expect(catalog).to receive(:apply).with(hash_including(one: true))
172
+ it "should apply the catalog with all options to :run" do
173
+ expect(@agent).to receive(:retrieve_catalog).and_return(@catalog)
138
174
 
139
- configurer.run(catalog: catalog, one: true)
175
+ expect(@catalog).to receive(:apply).with(hash_including(one: true))
176
+ @agent.run :one => true
177
+ end
178
+
179
+ it "should accept a catalog and use it instead of retrieving a different one" do
180
+ expect(@agent).not_to receive(:retrieve_catalog)
181
+
182
+ expect(@catalog).to receive(:apply)
183
+ @agent.run :one => true, :catalog => @catalog
140
184
  end
141
185
 
142
186
  it "should benchmark how long it takes to apply the catalog" do
143
- configurer.run(report: report)
187
+ expect(@agent).to receive(:benchmark).with(:notice, instance_of(String))
188
+
189
+ expect(@agent).to receive(:retrieve_catalog).and_return(@catalog)
144
190
 
145
- expect(report.logs).to include(an_object_having_attributes(level: :notice, message: /Applied catalog in .* seconds/))
191
+ expect(@catalog).not_to receive(:apply) # because we're not yielding
192
+ @agent.run
193
+ end
194
+
195
+ it "should execute post-run hooks after the run" do
196
+ expect(@agent).to receive(:execute_postrun_command)
197
+
198
+ @agent.run
146
199
  end
147
200
 
148
201
  it "should create report with passed transaction_uuid and job_id" do
149
- configurer = Puppet::Configurer.new("test_tuuid", "test_jid")
202
+ @agent = Puppet::Configurer.new("test_tuuid", "test_jid")
203
+ allow(@agent).to receive(:init_storage)
150
204
 
151
205
  report = Puppet::Transaction::Report.new(nil, "test", "aaaa")
152
206
  expect(Puppet::Transaction::Report).to receive(:new).with(anything, anything, 'test_tuuid', 'test_jid').and_return(report)
153
- expect(configurer).to receive(:send_report).with(report)
207
+ expect(@agent).to receive(:send_report).with(report)
154
208
 
155
- configurer.run
209
+ @agent.run
156
210
  end
157
211
 
158
212
  it "should send the report" do
159
213
  report = Puppet::Transaction::Report.new(nil, "test", "aaaa")
160
214
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
161
- expect(configurer).to receive(:send_report).with(report)
215
+ expect(@agent).to receive(:send_report).with(report)
162
216
 
163
217
  expect(report.environment).to eq("test")
164
218
  expect(report.transaction_uuid).to eq("aaaa")
165
219
 
166
- configurer.run
220
+ @agent.run
167
221
  end
168
222
 
169
223
  it "should send the transaction report even if the catalog could not be retrieved" do
170
- expect(configurer).to receive(:retrieve_catalog).and_return(nil)
224
+ expect(@agent).to receive(:retrieve_catalog).and_return(nil)
171
225
 
172
226
  report = Puppet::Transaction::Report.new(nil, "test", "aaaa")
173
227
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
174
- expect(configurer).to receive(:send_report).with(report)
228
+ expect(@agent).to receive(:send_report).with(report)
175
229
 
176
230
  expect(report.environment).to eq("test")
177
231
  expect(report.transaction_uuid).to eq("aaaa")
178
232
 
179
- configurer.run
233
+ @agent.run
180
234
  end
181
235
 
182
236
  it "should send the transaction report even if there is a failure" do
183
- expect(configurer).to receive(:retrieve_catalog).and_raise("whatever")
237
+ expect(@agent).to receive(:retrieve_catalog).and_raise("whatever")
184
238
 
185
239
  report = Puppet::Transaction::Report.new(nil, "test", "aaaa")
186
240
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
187
- expect(configurer).to receive(:send_report).with(report)
241
+ expect(@agent).to receive(:send_report).with(report)
188
242
 
189
243
  expect(report.environment).to eq("test")
190
244
  expect(report.transaction_uuid).to eq("aaaa")
191
245
 
192
- expect(configurer.run).to be_nil
246
+ expect(@agent.run).to be_nil
193
247
  end
194
248
 
195
249
  it "should remove the report as a log destination when the run is finished" do
250
+ report = Puppet::Transaction::Report.new
196
251
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
197
252
 
198
- configurer.run
253
+ @agent.run
199
254
 
200
255
  expect(Puppet::Util::Log.destinations).not_to include(report)
201
256
  end
202
257
 
203
258
  it "should return the report exit_status as the result of the run" do
259
+ report = Puppet::Transaction::Report.new
204
260
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
205
261
  expect(report).to receive(:exit_status).and_return(1234)
206
262
 
207
- expect(configurer.run).to eq(1234)
263
+ expect(@agent.run).to eq(1234)
208
264
  end
209
265
 
210
266
  it "should return nil if catalog application fails" do
211
- expect_any_instance_of(Puppet::Resource::Catalog).to receive(:apply).and_raise(Puppet::Error, 'One or more resource dependency cycles detected in graph')
212
- expect(configurer.run(catalog: catalog, report: report)).to be_nil
267
+ expect(@catalog).to receive(:apply).and_raise(Puppet::Error, 'One or more resource dependency cycles detected in graph')
268
+ report = Puppet::Transaction::Report.new
269
+ expect(@agent.run(catalog: @catalog, report: report)).to be_nil
213
270
  end
214
271
 
215
272
  it "should send the transaction report even if the pre-run command fails" do
273
+ report = Puppet::Transaction::Report.new
216
274
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
217
275
 
218
276
  Puppet.settings[:prerun_command] = "/my/command"
219
277
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
220
- expect(configurer).to receive(:send_report).with(report)
278
+ expect(@agent).to receive(:send_report).with(report)
221
279
 
222
- expect(configurer.run).to be_nil
280
+ expect(@agent.run).to be_nil
223
281
  end
224
282
 
225
283
  it "should include the pre-run command failure in the report" do
284
+ report = Puppet::Transaction::Report.new
226
285
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
227
286
 
228
287
  Puppet.settings[:prerun_command] = "/my/command"
229
288
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
230
289
 
231
- expect(configurer.run).to be_nil
290
+ expect(@agent.run).to be_nil
232
291
  expect(report.logs.find { |x| x.message =~ /Could not run command from prerun_command/ }).to be
233
292
  end
234
293
 
235
294
  it "should send the transaction report even if the post-run command fails" do
295
+ report = Puppet::Transaction::Report.new
236
296
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
237
297
 
238
298
  Puppet.settings[:postrun_command] = "/my/command"
239
299
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
240
- expect(configurer).to receive(:send_report).with(report)
300
+ expect(@agent).to receive(:send_report).with(report)
241
301
 
242
- expect(configurer.run).to be_nil
302
+ expect(@agent.run).to be_nil
243
303
  end
244
304
 
245
305
  it "should include the post-run command failure in the report" do
306
+ report = Puppet::Transaction::Report.new
246
307
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
247
308
 
248
309
  Puppet.settings[:postrun_command] = "/my/command"
@@ -250,7 +311,7 @@ describe Puppet::Configurer do
250
311
 
251
312
  expect(report).to receive(:<<) { |log, _| expect(log.message).to match(/Could not run command from postrun_command/) }.at_least(:once)
252
313
 
253
- expect(configurer.run).to be_nil
314
+ expect(@agent.run).to be_nil
254
315
  end
255
316
 
256
317
  it "should execute post-run command even if the pre-run command fails" do
@@ -259,42 +320,47 @@ describe Puppet::Configurer do
259
320
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/precommand"]).and_raise(Puppet::ExecutionFailure, "Failed")
260
321
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/postcommand"])
261
322
 
262
- expect(configurer.run).to be_nil
323
+ expect(@agent.run).to be_nil
263
324
  end
264
325
 
265
326
  it "should finalize the report" do
327
+ report = Puppet::Transaction::Report.new
266
328
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
267
329
 
268
330
  expect(report).to receive(:finalize_report)
269
- configurer.run
331
+ @agent.run
270
332
  end
271
333
 
272
334
  it "should not apply the catalog if the pre-run command fails" do
335
+ report = Puppet::Transaction::Report.new
273
336
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
274
337
 
275
338
  Puppet.settings[:prerun_command] = "/my/command"
276
339
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
277
340
 
278
- expect_any_instance_of(Puppet::Resource::Catalog).not_to receive(:apply)
279
- expect(configurer).to receive(:send_report)
341
+ expect(@catalog).not_to receive(:apply)
342
+ expect(@agent).to receive(:send_report)
280
343
 
281
- expect(configurer.run).to be_nil
344
+ expect(@agent.run).to be_nil
282
345
  end
283
346
 
284
347
  it "should apply the catalog, send the report, and return nil if the post-run command fails" do
348
+ report = Puppet::Transaction::Report.new
285
349
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
286
350
 
287
351
  Puppet.settings[:postrun_command] = "/my/command"
288
352
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
289
353
 
290
- expect_any_instance_of(Puppet::Resource::Catalog).to receive(:apply)
291
- expect(configurer).to receive(:send_report)
354
+ expect(@catalog).to receive(:apply)
355
+ expect(@agent).to receive(:send_report)
292
356
 
293
- expect(configurer.run).to be_nil
357
+ expect(@agent.run).to be_nil
294
358
  end
295
359
 
296
360
  it 'includes total time metrics in the report after successfully applying the catalog' do
297
- configurer.run(report: report)
361
+ report = Puppet::Transaction::Report.new
362
+ allow(@catalog).to receive(:apply).with(hash_including(report: report))
363
+ @agent.run(report: report)
298
364
 
299
365
  expect(report.metrics['time']).to be
300
366
  expect(report.metrics['time']['total']).to be_a_kind_of(Numeric)
@@ -304,15 +370,17 @@ describe Puppet::Configurer do
304
370
  Puppet.settings[:prerun_command] = "/my/command"
305
371
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
306
372
 
307
- configurer.run(report: report)
373
+ report = Puppet::Transaction::Report.new
374
+ @agent.run(report: report)
308
375
 
309
376
  expect(report.metrics['time']).to be
310
377
  expect(report.metrics['time']['total']).to be_a_kind_of(Numeric)
311
378
  end
312
379
 
313
380
  it 'includes total time metrics in the report even if catalog retrieval fails' do
314
- allow(configurer).to receive(:prepare_and_retrieve_catalog_from_cache).and_raise
315
- configurer.run(:report => report)
381
+ report = Puppet::Transaction::Report.new
382
+ allow(@agent).to receive(:prepare_and_retrieve_catalog_from_cache).and_raise
383
+ @agent.run(:report => report)
316
384
 
317
385
  expect(report.metrics['time']).to be
318
386
  expect(report.metrics['time']['total']).to be_a_kind_of(Numeric)
@@ -320,146 +388,159 @@ describe Puppet::Configurer do
320
388
 
321
389
  it "should refetch the catalog if the server specifies a new environment in the catalog" do
322
390
  catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote('second_env'))
323
- expect(configurer).to receive(:retrieve_catalog).and_return(catalog).twice
391
+ expect(@agent).to receive(:retrieve_catalog).and_return(catalog).twice
324
392
 
325
- configurer.run
393
+ @agent.run
326
394
  end
327
395
 
328
- it "changes the configurer's environment if the server specifies a new environment in the catalog" do
329
- allow_any_instance_of(Puppet::Resource::Catalog).to receive(:environment).and_return("second_env")
396
+ it "should change the environment setting if the server specifies a new environment in the catalog" do
397
+ allow(@catalog).to receive(:environment).and_return("second_env")
330
398
 
331
- configurer.run
399
+ @agent.run
332
400
 
333
- expect(configurer.environment).to eq("second_env")
401
+ expect(@agent.environment).to eq("second_env")
334
402
  end
335
403
 
336
- it "changes the report's environment if the server specifies a new environment in the catalog" do
337
- allow_any_instance_of(Puppet::Resource::Catalog).to receive(:environment).and_return("second_env")
404
+ it "should fix the report if the server specifies a new environment in the catalog" do
405
+ report = Puppet::Transaction::Report.new(nil, "test", "aaaa")
406
+ expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
407
+ expect(@agent).to receive(:send_report).with(report)
408
+
409
+ allow(@catalog).to receive(:environment).and_return("second_env")
410
+ allow(@agent).to receive(:retrieve_catalog).and_return(@catalog)
338
411
 
339
- configurer.run(report: report)
412
+ @agent.run
340
413
 
341
414
  expect(report.environment).to eq("second_env")
342
415
  end
343
416
 
344
417
  it "sends the transaction uuid in a catalog request" do
345
- configurer = Puppet::Configurer.new('aaa')
418
+ @agent.instance_variable_set(:@transaction_uuid, 'aaa')
346
419
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(transaction_uuid: 'aaa'))
347
- configurer.run
420
+ @agent.run
348
421
  end
349
422
 
350
423
  it "sends the transaction uuid in a catalog request" do
351
- configurer = Puppet::Configurer.new('b', 'aaa')
424
+ @agent.instance_variable_set(:@job_id, 'aaa')
352
425
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(job_id: 'aaa'))
353
- configurer.run
426
+ @agent.run
354
427
  end
355
428
 
356
429
  it "sets the static_catalog query param to true in a catalog request" do
357
430
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(static_catalog: true))
358
- configurer.run
431
+ @agent.run
359
432
  end
360
433
 
361
434
  it "sets the checksum_type query param to the default supported_checksum_types in a catalog request" do
362
435
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything,
363
436
  hash_including(checksum_type: 'md5.sha256.sha384.sha512.sha224'))
364
- configurer.run
437
+ @agent.run
365
438
  end
366
439
 
367
440
  it "sets the checksum_type query param to the supported_checksum_types setting in a catalog request" do
368
- Puppet[:supported_checksum_types] = ['sha256']
369
441
  # Regenerate the agent to pick up the new setting
370
- configurer = Puppet::Configurer.new
442
+ Puppet[:supported_checksum_types] = ['sha256']
443
+ @agent = Puppet::Configurer.new
444
+ allow(@agent).to receive(:init_storage)
445
+ allow(@agent).to receive(:download_plugins)
446
+ allow(@agent).to receive(:send_report)
447
+ allow(@agent).to receive(:save_last_run_summary)
371
448
 
372
449
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(checksum_type: 'sha256'))
373
- configurer.run
450
+ @agent.run
374
451
  end
375
452
 
376
453
  describe "when not using a REST terminus for catalogs" do
377
454
  it "should not pass any facts when retrieving the catalog" do
378
- # This is weird, we collect facts when constructing the node,
379
- # but we don't send them in the indirector request. Then the compiler
380
- # looks up the node, and collects its facts, which we could have sent
381
- # in the first place. This seems like a bug.
382
455
  Puppet::Resource::Catalog.indirection.terminus_class = :compiler
383
-
456
+ expect(@agent).not_to receive(:facts_for_uploading)
384
457
  expect(Puppet::Resource::Catalog.indirection).to receive(:find) do |name, options|
385
- expect(options[:facts]).to be_nil
386
- end.and_return(catalog)
458
+ options[:facts].nil?
459
+ end.and_return(@catalog)
387
460
 
388
- configurer.run
461
+ @agent.run
389
462
  end
390
463
  end
391
464
 
392
465
  describe "when using a REST terminus for catalogs" do
393
- it "should pass the url encoded facts and facts format as arguments when retrieving the catalog" do
466
+ it "should pass the prepared facts and the facts format as arguments when retrieving the catalog" do
394
467
  Puppet::Resource::Catalog.indirection.terminus_class = :rest
395
-
396
- facts.values = { 'foo' => 'bar' }
397
- Puppet::Node::Facts.indirection.save(facts)
398
-
399
- expect(
400
- Puppet::Resource::Catalog.indirection
401
- ).to receive(:find) do |_, options|
402
- expect(options[:facts_format]).to eq("application/json")
403
-
404
- unescaped = JSON.parse(CGI.unescape(options[:facts]))
405
- expect(unescaped).to include("values" => {"foo" => "bar"})
406
- end.and_return(catalog)
407
-
408
- configurer.run
468
+ # the "facts_for_uploading" are prepeared by first finding facts, and then encoding them
469
+ # this mocks the "find" with a special value 12345, which is then expected back in the
470
+ # call to "encode" - the encode in turn returns mocked data that is asserted as being
471
+ # presented to the catalog terminus as options.
472
+ #
473
+ expect(@agent).to receive(:find_facts).and_return(12345)
474
+ expect(@agent).to receive(:encode_facts).with(12345).and_return(:facts => "myfacts", :facts_format => :foo)
475
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(facts: "myfacts", facts_format: :foo)).and_return(@catalog)
476
+
477
+ @agent.run
409
478
  end
410
479
  end
411
480
  end
412
481
 
482
+ describe "when initialized with a transaction_uuid" do
483
+ it "stores it" do
484
+ expect(SecureRandom).not_to receive(:uuid)
485
+ configurer = Puppet::Configurer.new('foo')
486
+ expect(configurer.instance_variable_get(:@transaction_uuid) == 'foo')
487
+ end
488
+ end
489
+
413
490
  describe "when sending a report" do
414
491
  include PuppetSpec::Files
415
492
 
416
493
  before do
494
+ allow(Puppet.settings).to receive(:use).and_return(true)
495
+ @configurer = Puppet::Configurer.new
417
496
  Puppet[:lastrunfile] = tmpfile('last_run_file')
497
+
498
+ @report = Puppet::Transaction::Report.new
418
499
  Puppet[:reports] = "none"
419
500
  end
420
501
 
421
502
  it "should print a report summary if configured to do so" do
422
503
  Puppet.settings[:summarize] = true
423
504
 
424
- expect(report).to receive(:summary).and_return("stuff")
505
+ expect(@report).to receive(:summary).and_return("stuff")
425
506
 
426
- expect(configurer).to receive(:puts).with("stuff")
427
- configurer.send_report(report)
507
+ expect(@configurer).to receive(:puts).with("stuff")
508
+ @configurer.send_report(@report)
428
509
  end
429
510
 
430
511
  it "should not print a report summary if not configured to do so" do
431
512
  Puppet.settings[:summarize] = false
432
513
 
433
- expect(configurer).not_to receive(:puts)
434
- configurer.send_report(report)
514
+ expect(@configurer).not_to receive(:puts)
515
+ @configurer.send_report(@report)
435
516
  end
436
517
 
437
518
  it "should save the report if reporting is enabled" do
438
519
  Puppet.settings[:report] = true
439
520
 
440
- expect(Puppet::Transaction::Report.indirection).to receive(:save).with(report, nil, instance_of(Hash))
441
- configurer.send_report(report)
521
+ expect(Puppet::Transaction::Report.indirection).to receive(:save).with(@report, nil, instance_of(Hash))
522
+ @configurer.send_report(@report)
442
523
  end
443
524
 
444
525
  it "should not save the report if reporting is disabled" do
445
526
  Puppet.settings[:report] = false
446
527
 
447
- expect(Puppet::Transaction::Report.indirection).not_to receive(:save).with(report, nil, instance_of(Hash))
448
- configurer.send_report(report)
528
+ expect(Puppet::Transaction::Report.indirection).not_to receive(:save).with(@report, nil, instance_of(Hash))
529
+ @configurer.send_report(@report)
449
530
  end
450
531
 
451
532
  it "should save the last run summary if reporting is enabled" do
452
533
  Puppet.settings[:report] = true
453
534
 
454
- expect(configurer).to receive(:save_last_run_summary).with(report)
455
- configurer.send_report(report)
535
+ expect(@configurer).to receive(:save_last_run_summary).with(@report)
536
+ @configurer.send_report(@report)
456
537
  end
457
538
 
458
539
  it "should save the last run summary if reporting is disabled" do
459
540
  Puppet.settings[:report] = false
460
541
 
461
- expect(configurer).to receive(:save_last_run_summary).with(report)
462
- configurer.send_report(report)
542
+ expect(@configurer).to receive(:save_last_run_summary).with(@report)
543
+ @configurer.send_report(@report)
463
544
  end
464
545
 
465
546
  it "should log but not fail if saving the report fails" do
@@ -467,9 +548,8 @@ describe Puppet::Configurer do
467
548
 
468
549
  expect(Puppet::Transaction::Report.indirection).to receive(:save).and_raise("whatever")
469
550
 
470
- configurer.send_report(report)
471
-
472
- expect(@logs).to include(an_object_having_attributes(level: :err, message: 'Could not send report: whatever'))
551
+ expect(Puppet).to receive(:send_log).with(:err, 'Could not send report: whatever')
552
+ @configurer.send_report(@report)
473
553
  end
474
554
  end
475
555
 
@@ -477,17 +557,22 @@ describe Puppet::Configurer do
477
557
  include PuppetSpec::Files
478
558
 
479
559
  before do
560
+ allow(Puppet.settings).to receive(:use).and_return(true)
561
+ @configurer = Puppet::Configurer.new
562
+
563
+ @report = double('report', :raw_summary => {})
564
+
480
565
  Puppet[:lastrunfile] = tmpfile('last_run_file')
481
566
  end
482
567
 
483
568
  it "should write the last run file" do
484
- configurer.save_last_run_summary(report)
569
+ @configurer.save_last_run_summary(@report)
485
570
  expect(Puppet::FileSystem.exist?(Puppet[:lastrunfile])).to be_truthy
486
571
  end
487
572
 
488
573
  it "should write the raw summary as yaml" do
489
- expect(report).to receive(:raw_summary).and_return("summary")
490
- configurer.save_last_run_summary(report)
574
+ expect(@report).to receive(:raw_summary).and_return("summary")
575
+ @configurer.save_last_run_summary(@report)
491
576
  expect(File.read(Puppet[:lastrunfile])).to eq(YAML.dump("summary"))
492
577
  end
493
578
 
@@ -502,14 +587,13 @@ describe Puppet::Configurer do
502
587
 
503
588
  expect(Puppet::Util).to receive(:replace_file).and_yield(fh)
504
589
 
505
- configurer.save_last_run_summary(report)
506
-
507
- expect(@logs).to include(an_object_having_attributes(level: :err, message: 'Could not save last run local report: failed to do print'))
590
+ expect(Puppet).to receive(:send_log).with(:err, 'Could not save last run local report: failed to do print')
591
+ @configurer.save_last_run_summary(@report)
508
592
  end
509
593
 
510
594
  it "should create the last run file with the correct mode" do
511
595
  expect(Puppet.settings.setting(:lastrunfile)).to receive(:mode).and_return('664')
512
- configurer.save_last_run_summary(report)
596
+ @configurer.save_last_run_summary(@report)
513
597
 
514
598
  if Puppet::Util::Platform.windows?
515
599
  require 'puppet/util/windows/security'
@@ -522,28 +606,26 @@ describe Puppet::Configurer do
522
606
 
523
607
  it "should report invalid last run file permissions" do
524
608
  expect(Puppet.settings.setting(:lastrunfile)).to receive(:mode).and_return('892')
525
-
526
- configurer.save_last_run_summary(report)
527
-
528
- expect(@logs).to include(an_object_having_attributes(level: :err, message: /Could not save last run local report.*892 is invalid/))
609
+ expect(Puppet).to receive(:send_log).with(:err, /Could not save last run local report.*892 is invalid/)
610
+ @configurer.save_last_run_summary(@report)
529
611
  end
530
612
  end
531
613
 
532
614
  describe "when requesting a node" do
533
615
  it "uses the transaction uuid in the request" do
534
616
  expect(Puppet::Node.indirection).to receive(:find).with(anything, hash_including(transaction_uuid: anything)).twice
535
- configurer.run
617
+ @agent.run
536
618
  end
537
619
 
538
620
  it "sends an explicitly configured environment request" do
539
621
  expect(Puppet.settings).to receive(:set_by_config?).with(:environment).and_return(true)
540
622
  expect(Puppet::Node.indirection).to receive(:find).with(anything, hash_including(configured_environment: Puppet[:environment])).twice
541
- configurer.run
623
+ @agent.run
542
624
  end
543
625
 
544
626
  it "does not send a configured_environment when using the default" do
545
627
  expect(Puppet::Node.indirection).to receive(:find).with(anything, hash_including(configured_environment: nil)).twice
546
- configurer.run
628
+ @agent.run
547
629
  end
548
630
  end
549
631
 
@@ -574,6 +656,14 @@ describe Puppet::Configurer do
574
656
 
575
657
  describe "when retrieving a catalog" do
576
658
  before do
659
+ allow(Puppet.settings).to receive(:use).and_return(true)
660
+ allow(@agent).to receive(:facts_for_uploading).and_return({})
661
+ allow(@agent).to receive(:download_plugins)
662
+
663
+ # retrieve a catalog in the current environment, so we don't try to converge unexpectedly
664
+ @catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote(Puppet[:environment].to_sym))
665
+
666
+ # this is the default when using a Configurer instance
577
667
  allow(Puppet::Resource::Catalog.indirection).to receive(:terminus_class).and_return(:rest)
578
668
  end
579
669
 
@@ -583,139 +673,100 @@ describe Puppet::Configurer do
583
673
  end
584
674
 
585
675
  it "should first look in the cache for a catalog" do
586
- expects_cached_catalog_only(catalog)
676
+ expects_cached_catalog_only(@catalog)
587
677
 
588
- configurer.run
678
+ expect(@agent.retrieve_catalog({})).to eq(@catalog)
589
679
  end
590
680
 
591
681
  it "should not make a node request or pluginsync when a cached catalog is successfully retrieved" do
592
682
  expect(Puppet::Node.indirection).not_to receive(:find)
593
- expects_cached_catalog_only(catalog)
594
- expect(configurer).not_to receive(:download_plugins)
683
+ expects_cached_catalog_only(@catalog)
684
+ expect(@agent).not_to receive(:download_plugins)
595
685
 
596
- configurer.run
686
+ @agent.run
597
687
  end
598
688
 
599
689
  it "should make a node request and pluginsync when a cached catalog cannot be retrieved" do
600
690
  expect(Puppet::Node.indirection).to receive(:find).and_return(nil)
601
- expects_fallback_to_new_catalog(catalog)
602
- expect(configurer).to receive(:download_plugins)
691
+ expects_fallback_to_new_catalog(@catalog)
692
+ expect(@agent).to receive(:download_plugins)
603
693
 
604
- configurer.run
694
+ @agent.run
605
695
  end
606
696
 
607
697
  it "should set its cached_catalog_status to 'explicitly_requested'" do
608
- expects_cached_catalog_only(catalog)
698
+ expects_cached_catalog_only(@catalog)
609
699
 
610
- options = {}
611
- configurer.run(options)
612
-
613
- expect(options[:report].cached_catalog_status).to eq('explicitly_requested')
700
+ @agent.retrieve_catalog({})
701
+ expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('explicitly_requested')
614
702
  end
615
703
 
616
704
  it "should set its cached_catalog_status to 'explicitly requested' if the cached catalog is from a different environment" do
617
705
  cached_catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote('second_env'))
618
706
  expects_cached_catalog_only(cached_catalog)
619
707
 
620
- options = {}
621
- configurer.run(options)
622
-
623
- expect(options[:report].cached_catalog_status).to eq('explicitly_requested')
708
+ @agent.retrieve_catalog({})
709
+ expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('explicitly_requested')
624
710
  end
625
711
 
626
- it "should pluginsync and compile a new catalog if none is found in the cache" do
627
- expects_fallback_to_new_catalog(catalog)
628
- stub_request(:get, %r{/puppet/v3/file_metadatas?/plugins}).to_return(:status => 404)
629
- stub_request(:get, %r{/puppet/v3/file_metadatas?/pluginfacts}).to_return(:status => 404)
712
+ it "should compile a new catalog if none is found in the cache" do
713
+ expects_fallback_to_new_catalog(@catalog)
714
+
715
+ expect(@agent.retrieve_catalog({})).to eq(@catalog)
716
+ end
630
717
 
631
- options = {}
632
- configurer.run(options)
718
+ it "should set its cached_catalog_status to 'not_used' if no catalog is found in the cache" do
719
+ expects_fallback_to_new_catalog(@catalog)
633
720
 
634
- expect(options[:report].cached_catalog_status).to eq('not_used')
721
+ @agent.retrieve_catalog({})
722
+ expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('not_used')
635
723
  end
636
724
 
637
725
  it "should not attempt to retrieve a cached catalog again if the first attempt failed" do
638
726
  expect(Puppet::Node.indirection).to receive(:find).and_return(nil)
639
727
  expects_neither_new_or_cached_catalog
640
728
 
641
- # after failing to use a cached catalog, we'll need to pluginsync before getting
642
- # a new catalog, which also fails.
643
- stub_request(:get, %r{/puppet/v3/file_metadatas?/plugins}).to_return(:status => 404)
644
- stub_request(:get, %r{/puppet/v3/file_metadatas?/pluginfacts}).to_return(:status => 404)
645
-
646
- configurer.run
729
+ @agent.run
647
730
  end
648
731
 
649
732
  it "should return the cached catalog when the environment doesn't match" do
650
733
  cached_catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote('second_env'))
651
734
  expects_cached_catalog_only(cached_catalog)
652
735
 
653
- allow(Puppet).to receive(:info)
654
736
  expect(Puppet).to receive(:info).with("Using cached catalog from environment 'second_env'")
655
-
656
- configurer.run
657
- end
658
-
659
- it "applies the catalog passed as options when the catalog cache terminus is not set" do
660
- stub_request(:get, %r{/puppet/v3/file_metadatas?/plugins}).to_return(:status => 404)
661
- stub_request(:get, %r{/puppet/v3/file_metadatas?/pluginfacts}).to_return(:status => 404)
662
-
663
- catalog.add_resource(Puppet::Resource.new('notify', 'from apply'))
664
- configurer.run(catalog: catalog.to_ral)
665
-
666
- # make sure cache class is not set to avoid surprises later
667
- expect(Puppet::Resource::Catalog.indirection).to_not be_cache
668
- expect(@logs).to include(an_object_having_attributes(level: :notice, message: /defined 'message' as 'from apply'/))
669
- end
670
-
671
- it "applies the cached catalog when the catalog cache terminus is set, ignoring the catalog passed as options" do
672
- Puppet::Resource::Catalog.indirection.cache_class = :json
673
-
674
- cached_catalog = Puppet::Resource::Catalog.new(Puppet[:node_name_value], Puppet[:environment])
675
- cached_catalog.add_resource(Puppet::Resource.new('notify', 'from cache'))
676
-
677
- # update cached catalog
678
- Puppet.settings.use(:main, :agent)
679
- path = Puppet::Resource::Catalog.indirection.cache.path(cached_catalog.name)
680
- FileUtils.mkdir(File.dirname(path))
681
- File.write(path, cached_catalog.render(:json))
682
-
683
- configurer.run(catalog: catalog.to_ral)
684
-
685
- expect(@logs).to include(an_object_having_attributes(level: :notice, message: /defined 'message' as 'from cache'/))
737
+ expect(@agent.retrieve_catalog({})).to eq(cached_catalog)
686
738
  end
687
739
  end
688
740
 
689
741
  describe "and strict environment mode is set" do
690
742
  before do
743
+ allow(@catalog).to receive(:to_ral).and_return(@catalog)
744
+ allow(@catalog).to receive(:write_class_file)
745
+ allow(@catalog).to receive(:write_resource_file)
746
+ allow(@agent).to receive(:send_report)
747
+ allow(@agent).to receive(:save_last_run_summary)
691
748
  Puppet.settings[:strict_environment_mode] = true
692
749
  end
693
750
 
694
751
  it "should not make a node request" do
695
- stub_request(:get, %r{/puppet/v3/file_metadatas?/plugins}).to_return(:status => 404)
696
- stub_request(:get, %r{/puppet/v3/file_metadatas?/pluginfacts}).to_return(:status => 404)
697
- expects_new_catalog_only(catalog)
698
-
699
752
  expect(Puppet::Node.indirection).not_to receive(:find)
700
753
 
701
- configurer.run
754
+ @agent.run
702
755
  end
703
756
 
704
757
  it "should return nil when the catalog's environment doesn't match the agent specified environment" do
705
- Puppet[:environment] = 'second_env'
706
- configurer = Puppet::Configurer.new
707
-
708
- catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote("production"))
709
- expects_new_catalog_only(catalog)
758
+ @agent.instance_variable_set(:@environment, 'second_env')
759
+ expects_new_catalog_only(@catalog)
710
760
 
711
761
  expect(Puppet).to receive(:err).with("Not using catalog because its environment 'production' does not match agent specified environment 'second_env' and strict_environment_mode is set")
712
- expect(configurer.run).to be_nil
762
+ expect(@agent.run).to be_nil
713
763
  end
714
764
 
715
- it "should return 0 when the catalog's environment matches the agent specified environment" do
716
- expects_new_catalog_only(catalog)
765
+ it "should not return nil when the catalog's environment matches the agent specified environment" do
766
+ @agent.instance_variable_set(:@environment, 'production')
767
+ expects_new_catalog_only(@catalog)
717
768
 
718
- expect(configurer.run).to eq(0)
769
+ expect(@agent.run).to eq(0)
719
770
  end
720
771
 
721
772
  describe "and a cached catalog is explicitly requested" do
@@ -724,81 +775,83 @@ describe Puppet::Configurer do
724
775
  end
725
776
 
726
777
  it "should return nil when the cached catalog's environment doesn't match the agent specified environment" do
727
- Puppet[:environment] = 'second_env'
728
- configurer = Puppet::Configurer.new
729
-
730
- catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote("production"))
731
- expects_cached_catalog_only(catalog)
778
+ @agent.instance_variable_set(:@environment, 'second_env')
779
+ expects_cached_catalog_only(@catalog)
732
780
 
733
781
  expect(Puppet).to receive(:err).with("Not using catalog because its environment 'production' does not match agent specified environment 'second_env' and strict_environment_mode is set")
734
- expect(configurer.run).to be_nil
782
+ expect(@agent.run).to be_nil
735
783
  end
736
784
 
737
785
  it "should proceed with the cached catalog if its environment matchs the local environment" do
738
- expects_cached_catalog_only(catalog)
786
+ Puppet.settings[:use_cached_catalog] = true
787
+ @agent.instance_variable_set(:@environment, 'production')
788
+ expects_cached_catalog_only(@catalog)
739
789
 
740
- expect(configurer.run).to eq(0)
790
+ expect(@agent.run).to eq(0)
741
791
  end
742
792
  end
743
793
  end
744
794
 
745
- it "should set its cached_catalog_status to 'not_used' when downloading a new catalog" do
746
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true)).and_return(catalog)
795
+ it "should use the Catalog class to get its catalog" do
796
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).and_return(@catalog)
747
797
 
748
- options = {}
749
- configurer.run(options)
798
+ @agent.retrieve_catalog({})
799
+ end
750
800
 
751
- expect(options[:report].cached_catalog_status).to eq('not_used')
801
+ it "should set its cached_catalog_status to 'not_used' when downloading a new catalog" do
802
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true)).and_return(@catalog)
803
+
804
+ @agent.retrieve_catalog({})
805
+ expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('not_used')
752
806
  end
753
807
 
754
808
  it "should use its node_name_value to retrieve the catalog" do
755
- myhost_facts = Puppet::Node::Facts.new("myhost.domain.com")
756
- Puppet::Node::Facts.indirection.save(myhost_facts)
757
-
809
+ allow(Facter).to receive(:value).and_return("eh")
758
810
  Puppet.settings[:node_name_value] = "myhost.domain.com"
759
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with("myhost.domain.com", anything).and_return(catalog)
811
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with("myhost.domain.com", anything).and_return(@catalog)
760
812
 
761
- configurer.run
813
+ @agent.retrieve_catalog({})
762
814
  end
763
815
 
764
- it "should log when no catalog can be retrieved from the server" do
765
- expects_fallback_to_cached_catalog(catalog)
816
+ it "should default to returning a catalog retrieved directly from the server, skipping the cache" do
817
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true)).and_return(@catalog)
818
+
819
+ expect(@agent.retrieve_catalog({})).to eq(@catalog)
820
+ end
821
+
822
+ it "should log and return the cached catalog when no catalog can be retrieved from the server" do
823
+ expects_fallback_to_cached_catalog(@catalog)
766
824
 
767
- allow(Puppet).to receive(:info)
768
825
  expect(Puppet).to receive(:info).with("Using cached catalog from environment 'production'")
769
- configurer.run
826
+ expect(@agent.retrieve_catalog({})).to eq(@catalog)
770
827
  end
771
828
 
772
829
  it "should set its cached_catalog_status to 'on_failure' when no catalog can be retrieved from the server" do
773
- expects_fallback_to_cached_catalog(catalog)
830
+ expects_fallback_to_cached_catalog(@catalog)
774
831
 
775
- options = {}
776
- configurer.run(options)
777
-
778
- expect(options[:report].cached_catalog_status).to eq('on_failure')
832
+ @agent.retrieve_catalog({})
833
+ expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('on_failure')
779
834
  end
780
835
 
781
836
  it "should not look in the cache for a catalog if one is returned from the server" do
782
- expects_new_catalog_only(catalog)
837
+ expects_new_catalog_only(@catalog)
783
838
 
784
- configurer.run
839
+ expect(@agent.retrieve_catalog({})).to eq(@catalog)
785
840
  end
786
841
 
787
842
  it "should return the cached catalog when retrieving the remote catalog throws an exception" do
788
843
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true)).and_raise("eh")
789
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_terminus: true)).and_return(catalog)
844
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_terminus: true)).and_return(@catalog)
790
845
 
791
- configurer.run
846
+ expect(@agent.retrieve_catalog({})).to eq(@catalog)
792
847
  end
793
848
 
794
849
  it "should set its cached_catalog_status to 'on_failure' when retrieving the remote catalog throws an exception" do
795
850
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true)).and_raise("eh")
796
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_terminus: true)).and_return(catalog)
797
-
798
- options = {}
799
- configurer.run(options)
851
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_terminus: true)).and_return(@catalog)
800
852
 
801
- expect(options[:report].cached_catalog_status).to eq('on_failure')
853
+ @agent.retrieve_catalog({})
854
+ expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('on_failure')
802
855
  end
803
856
 
804
857
  it "should log and return nil if no catalog can be retrieved from the server and :usecacheonfailure is disabled" do
@@ -807,173 +860,120 @@ describe Puppet::Configurer do
807
860
 
808
861
  expect(Puppet).to receive(:warning).with('Not using cache on failed catalog')
809
862
 
810
- expect(configurer.run).to be_nil
863
+ expect(@agent.retrieve_catalog({})).to be_nil
811
864
  end
812
865
 
813
866
  it "should set its cached_catalog_status to 'not_used' if no catalog can be retrieved from the server and :usecacheonfailure is disabled or fails to retrieve a catalog" do
814
867
  Puppet[:usecacheonfailure] = false
815
868
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true)).and_return(nil)
816
869
 
817
- options = {}
818
- configurer.run(options)
819
-
820
- expect(options[:report].cached_catalog_status).to eq('not_used')
870
+ @agent.retrieve_catalog({})
871
+ expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('not_used')
821
872
  end
822
873
 
823
874
  it "should return nil if no cached catalog is available and no catalog can be retrieved from the server" do
824
875
  expects_neither_new_or_cached_catalog
825
876
 
826
- expect(configurer.run).to be_nil
877
+ expect(@agent.retrieve_catalog({})).to be_nil
827
878
  end
828
879
 
829
880
  it "should return nil if its cached catalog environment doesn't match server-specified environment" do
830
881
  cached_catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote('second_env'))
882
+ @agent.instance_variable_set(:@node_environment, 'production')
831
883
 
832
884
  expects_fallback_to_cached_catalog(cached_catalog)
833
885
 
834
- allow(Puppet).to receive(:err)
835
886
  expect(Puppet).to receive(:err).with("Not using cached catalog because its environment 'second_env' does not match 'production'")
836
- expect(configurer.run).to be_nil
887
+ expect(@agent.retrieve_catalog({})).to be_nil
837
888
  end
838
889
 
839
890
  it "should set its cached_catalog_status to 'not_used' if the cached catalog environment doesn't match server-specified environment" do
840
891
  cached_catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote('second_env'))
892
+ @agent.instance_variable_set(:@node_environment, 'production')
841
893
 
842
894
  expects_fallback_to_cached_catalog(cached_catalog)
843
895
 
844
- options = {}
845
- configurer.run(options)
846
- expect(options[:report].cached_catalog_status).to eq('not_used')
896
+ @agent.retrieve_catalog({})
897
+ expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('not_used')
847
898
  end
848
899
 
849
- it "should set its cached_catalog_status to 'on_failure' if the cached catalog environment matches server-specified environment" do
850
- expects_fallback_to_cached_catalog(catalog)
900
+ it "should return its cached catalog if the environment matches the server-specified environment" do
901
+ cached_catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote(Puppet[:environment]))
902
+ @agent.instance_variable_set(:@node_environment, cached_catalog.environment)
851
903
 
852
- options = {}
853
- configurer.run(options)
854
- expect(options[:report].cached_catalog_status).to eq('on_failure')
855
- end
856
-
857
- it "should not update the cached catalog in noop mode" do
858
- Puppet[:noop] = true
859
-
860
- stub_request(:get, %r{/puppet/v3/catalog}).to_return(:status => 200, :body => catalog.render(:json), :headers => {'Content-Type' => 'application/json'})
861
-
862
- Puppet::Resource::Catalog.indirection.cache_class = :json
863
- path = Puppet::Resource::Catalog.indirection.cache.path(catalog.name)
904
+ expects_fallback_to_cached_catalog(cached_catalog)
864
905
 
865
- expect(File).to_not be_exist(path)
866
- configurer.run
867
- expect(File).to_not be_exist(path)
906
+ expect(@agent.retrieve_catalog({})).to eq(cached_catalog)
868
907
  end
869
908
 
870
- it "should update the cached catalog when not in noop mode" do
871
- Puppet[:noop] = false
872
- Puppet[:log_level] = 'info'
873
-
874
- stub_request(:get, %r{/puppet/v3/catalog}).to_return(:status => 200, :body => catalog.render(:json), :headers => {'Content-Type' => 'application/json'})
875
-
876
- Puppet::Resource::Catalog.indirection.cache_class = :json
877
- cache_path = Puppet::Resource::Catalog.indirection.cache.path(Puppet[:node_name_value])
909
+ it "should set its cached_catalog_status to 'on_failure' if the cached catalog environment matches server-specified environment" do
910
+ cached_catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote(Puppet[:environment]))
911
+ @agent.instance_variable_set(:@node_environment, cached_catalog.environment)
878
912
 
879
- expect(File).to_not be_exist(cache_path)
880
- configurer.run
881
- expect(File).to be_exist(cache_path)
913
+ expects_fallback_to_cached_catalog(cached_catalog)
882
914
 
883
- expect(@logs).to include(an_object_having_attributes(level: :info, message: "Caching catalog for #{Puppet[:node_name_value]}"))
915
+ @agent.retrieve_catalog({})
916
+ expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('on_failure')
884
917
  end
885
918
 
886
- it "successfully applies the catalog without a cache" do
887
- stub_request(:get, %r{/puppet/v3/catalog}).to_return(:status => 200, :body => catalog.render(:json), :headers => {'Content-Type' => 'application/json'})
888
-
889
- Puppet::Resource::Catalog.indirection.cache_class = nil
919
+ it "should not update the cached catalog in noop mode" do
920
+ Puppet[:noop] = true
921
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true, ignore_cache_save: true)).and_return(@catalog)
890
922
 
891
- expect(configurer.run).to eq(0)
923
+ @agent.retrieve_catalog({})
892
924
  end
893
925
 
894
- it "should not update the cached catalog when running puppet apply" do
895
- Puppet::Resource::Catalog.indirection.cache_class = :json
896
- path = Puppet::Resource::Catalog.indirection.cache.path(catalog.name)
926
+ it "should update the cached catalog when not in noop mode" do
927
+ Puppet[:noop] = false
928
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true, ignore_cache_save: false)).and_return(@catalog)
897
929
 
898
- expect(File).to_not be_exist(path)
899
- configurer.run(catalog: catalog)
900
- expect(File).to_not be_exist(path)
930
+ @agent.retrieve_catalog({})
901
931
  end
902
932
  end
903
933
 
904
- describe "when converging the environment" do
905
- let(:apple) { Puppet::Resource::Catalog.new(Puppet[:node_name_value], Puppet::Node::Environment.remote('apple')) }
906
- let(:banana) { Puppet::Resource::Catalog.new(Puppet[:node_name_value], Puppet::Node::Environment.remote('banana')) }
934
+ describe "when converting the catalog" do
935
+ before do
936
+ allow(Puppet.settings).to receive(:use).and_return(true)
907
937
 
908
- before :each do
909
- apple.add_resource(resource)
910
- banana.add_resource(resource)
938
+ allow(catalog).to receive(:to_ral).and_return(ral_catalog)
911
939
  end
912
940
 
913
- it "converges after multiple attempts" do
914
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).and_return(apple, banana, banana)
915
-
916
- allow(Puppet).to receive(:notice)
917
- expect(Puppet).to receive(:notice).with("Local environment: 'production' doesn't match server specified environment 'apple', restarting agent run with environment 'apple'")
918
- expect(Puppet).to receive(:notice).with("Local environment: 'apple' doesn't match server specified environment 'banana', restarting agent run with environment 'banana'")
941
+ let (:catalog) { Puppet::Resource::Catalog.new('tester', Puppet::Node::Environment.remote(Puppet[:environment].to_sym)) }
942
+ let (:ral_catalog) { Puppet::Resource::Catalog.new('tester', Puppet::Node::Environment.remote(Puppet[:environment].to_sym)) }
919
943
 
920
- configurer.run
944
+ it "should convert the catalog to a RAL-formed catalog" do
945
+ expect(@agent.convert_catalog(catalog, 10)).to equal(ral_catalog)
921
946
  end
922
947
 
923
- it "raises if it can't converge after 4 tries after the initial catalog request" do
924
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).and_return(apple, banana, apple, banana, apple)
948
+ it "should finalize the catalog" do
949
+ expect(ral_catalog).to receive(:finalize)
925
950
 
926
- configurer.run
927
-
928
- expect(@logs).to include(an_object_having_attributes(level: :err, message: "Failed to apply catalog: Catalog environment didn't stabilize after 4 fetches, aborting run"))
951
+ @agent.convert_catalog(catalog, 10)
929
952
  end
930
- end
931
953
 
932
- describe "when converting the catalog" do
933
- it "converts Puppet::Resource into Puppet::Type::Notify" do
934
- expect(configurer).to receive(:apply_catalog) do |ral, _|
935
- expect(ral.resources).to contain(an_instance_of(Puppet::Type::Notify))
936
- end
954
+ it "should record the passed retrieval time with the RAL catalog" do
955
+ expect(ral_catalog).to receive(:retrieval_duration=).with(10)
937
956
 
938
- configurer.run(catalog: catalog)
957
+ @agent.convert_catalog(catalog, 10)
939
958
  end
940
959
 
941
- it "adds default schedules" do
942
- expect(configurer).to receive(:apply_catalog) do |ral, _|
943
- expect(ral.resources.map(&:to_ref)).to contain(%w{Schedule[puppet] Schedule[hourly] Schedule[daily] Schedule[weekly] Schedule[monthly] Schedule[never]})
944
- end
945
-
946
- configurer.run
947
- end
948
-
949
- it "records the retrieval duration to the catalog" do
950
- expect(configurer).to receive(:apply_catalog) do |ral, _|
951
- expect(ral.retrieval_duration).to be_an_instance_of(Float)
952
- end
960
+ it "should write the RAL catalog's class file" do
961
+ expect(ral_catalog).to receive(:write_class_file)
953
962
 
954
- configurer.run
963
+ @agent.convert_catalog(catalog, 10)
955
964
  end
956
965
 
957
- it "writes the class file containing applied settings classes" do
958
- expect(File).to_not be_exist(Puppet[:classfile])
959
-
960
- configurer.run
966
+ it "should write the RAL catalog's resource file" do
967
+ expect(ral_catalog).to receive(:write_resource_file)
961
968
 
962
- expect(File.read(Puppet[:classfile]).chomp).to eq('settings')
969
+ @agent.convert_catalog(catalog, 10)
963
970
  end
964
971
 
965
- it "writes an empty resource file since no resources are 'managed'" do
966
- expect(File).to_not be_exist(Puppet[:resourcefile])
972
+ it "should set catalog conversion time on the report" do
973
+ report = Puppet::Transaction::Report.new
967
974
 
968
- configurer.run
969
-
970
- expect(File.read(Puppet[:resourcefile]).chomp).to eq("")
971
- end
972
-
973
- it "adds the conversion time to the report" do
974
- configurer.run(report: report)
975
-
976
- expect(report.metrics['time']['convert_catalog']).to be_an_instance_of(Float)
975
+ expect(report).to receive(:add_times).with(:convert_catalog, kind_of(Numeric))
976
+ @agent.convert_catalog(catalog, 10, {:report => report})
977
977
  end
978
978
  end
979
979
 
@@ -994,62 +994,66 @@ describe Puppet::Configurer do
994
994
  describe "when attempting failover" do
995
995
  it "should not failover if server_list is not set" do
996
996
  Puppet.settings[:server_list] = []
997
- configurer.run
997
+ expect(@agent).not_to receive(:find_functional_server)
998
+ @agent.run
998
999
  end
999
1000
 
1000
1001
  it "should not failover during an apply run" do
1001
1002
  Puppet.settings[:server_list] = ["myserver:123"]
1003
+ expect(@agent).not_to receive(:find_functional_server)
1002
1004
  catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote(Puppet[:environment].to_sym))
1003
- configurer.run(catalog: catalog)
1005
+ @agent.run :catalog => catalog
1004
1006
  end
1005
1007
 
1006
- it "should select a server when it receives 200 OK response" do
1008
+ it "should select a server when provided" do
1007
1009
  Puppet.settings[:server_list] = ["myserver:123"]
1008
-
1009
- stub_request(:get, 'https://myserver:123/status/v1/simple/master').to_return(status: 200)
1010
+ response = Net::HTTPOK.new(nil, 200, 'OK')
1011
+ allow(Puppet::Network::HttpPool).to receive(:connection).with('myserver', 123, anything).and_return(double('request', get: response))
1012
+ allow(@agent).to receive(:run_internal)
1010
1013
 
1011
1014
  options = {}
1012
- configurer.run(options)
1015
+ @agent.run(options)
1013
1016
  expect(options[:report].master_used).to eq('myserver:123')
1014
1017
  end
1015
1018
 
1016
- it "should report when a server is unavailable" do
1019
+ it "queries the simple status for the 'master' service" do
1017
1020
  Puppet.settings[:server_list] = ["myserver:123"]
1021
+ response = Net::HTTPOK.new(nil, 200, 'OK')
1022
+ http = double('request')
1023
+ expect(http).to receive(:get).with('/status/v1/simple/master').and_return(response)
1024
+ allow(Puppet::Network::HttpPool).to receive(:connection).with('myserver', 123, anything).and_return(http)
1025
+ allow(@agent).to receive(:run_internal)
1018
1026
 
1019
- stub_request(:get, 'https://myserver:123/status/v1/simple/master').to_return(status: [500, "Internal Server Error"])
1027
+ @agent.run
1028
+ end
1020
1029
 
1021
- allow(Puppet).to receive(:debug)
1022
- expect(Puppet).to receive(:debug).with("Puppet server myserver:123 is unavailable: 500 Internal Server Error")
1030
+ it "should report when a server is unavailable" do
1031
+ Puppet.settings[:server_list] = ["myserver:123"]
1032
+ response = Net::HTTPInternalServerError.new(nil, 500, 'Internal Server Error')
1033
+ allow(Puppet::Network::HttpPool).to receive(:connection).with('myserver', 123, anything).and_return(double('request', get: response))
1023
1034
 
1024
- expect {
1025
- configurer.run
1026
- }.to raise_error(Puppet::Error, /Could not select a functional puppet master from server_list:/)
1035
+ expect(Puppet).to receive(:debug).with("Puppet server myserver:123 is unavailable: 500 Internal Server Error")
1036
+ expect{ @agent.run }.to raise_error(Puppet::Error, /Could not select a functional puppet master from server_list/)
1027
1037
  end
1028
1038
 
1029
1039
  it "should error when no servers in 'server_list' are reachable" do
1030
- Puppet.settings[:server_list] = "myserver:123,someotherservername"
1031
-
1032
- stub_request(:get, 'https://myserver:123/status/v1/simple/master').to_return(status: 400)
1033
- stub_request(:get, 'https://someotherservername:8140/status/v1/simple/master').to_return(status: 400)
1040
+ Puppet.settings[:server_list] = ["myserver:123"]
1041
+ error = Net::HTTPError.new(400, 'dummy server communication error')
1042
+ allow(Puppet::Network::HttpPool).to receive(:connection).with('myserver', 123, anything).and_return(double('request', get: error))
1034
1043
 
1035
- expect{
1036
- configurer.run
1037
- }.to raise_error(Puppet::Error, /Could not select a functional puppet master from server_list: 'myserver:123,someotherservername'/)
1044
+ options = {}
1045
+ expect{ @agent.run(options) }.to raise_error(Puppet::Error, /Could not select a functional puppet master from server_list/)
1046
+ expect(options[:report].master_used).to be_nil
1038
1047
  end
1039
1048
 
1040
1049
  it "should not make multiple node requests when the server is found" do
1041
1050
  Puppet.settings[:server_list] = ["myserver:123"]
1051
+ response = Net::HTTPOK.new(nil, 200, 'OK')
1042
1052
 
1043
- Puppet::Node.indirection.terminus_class = :rest
1044
- Puppet::Resource::Catalog.indirection.terminus_class = :rest
1045
-
1046
- stub_request(:get, 'https://myserver:123/status/v1/simple/master').to_return(status: 200)
1047
- stub_request(:get, %r{https://myserver:123/puppet/v3/catalog}).to_return(status: 200)
1048
- node_request = stub_request(:get, %r{https://myserver:123/puppet/v3/node/}).to_return(status: 200)
1049
-
1050
- configurer.run
1053
+ expect(Puppet::Network::HttpPool).to receive(:connection).with('myserver', 123, anything).and_return(double('request', get: response))
1054
+ allow(@agent).to receive(:run_internal)
1051
1055
 
1052
- expect(node_request).to have_been_requested.once
1056
+ @agent.run
1053
1057
  end
1054
1058
  end
1055
1059
  end