puppet 6.13.0-x86-mingw32 → 6.18.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 (461) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +2 -7
  3. data/CONTRIBUTING.md +7 -13
  4. data/Gemfile +4 -2
  5. data/Gemfile.lock +36 -32
  6. data/README.md +17 -24
  7. data/ext/windows/service/daemon.rb +3 -3
  8. data/lib/puppet.rb +33 -9
  9. data/lib/puppet/agent.rb +20 -14
  10. data/lib/puppet/application/agent.rb +26 -17
  11. data/lib/puppet/application/apply.rb +18 -20
  12. data/lib/puppet/application/describe.rb +7 -5
  13. data/lib/puppet/application/device.rb +2 -2
  14. data/lib/puppet/application/filebucket.rb +19 -15
  15. data/lib/puppet/application/lookup.rb +16 -4
  16. data/lib/puppet/application/plugin.rb +1 -0
  17. data/lib/puppet/application/ssl.rb +4 -4
  18. data/lib/puppet/configurer.rb +58 -57
  19. data/lib/puppet/configurer/downloader.rb +31 -10
  20. data/lib/puppet/configurer/plugin_handler.rb +10 -1
  21. data/lib/puppet/confine.rb +2 -2
  22. data/lib/puppet/confine/any.rb +1 -1
  23. data/lib/puppet/context/trusted_information.rb +14 -8
  24. data/lib/puppet/daemon.rb +13 -27
  25. data/lib/puppet/defaults.rb +92 -12
  26. data/lib/puppet/environments.rb +4 -5
  27. data/lib/puppet/face/facts.rb +1 -1
  28. data/lib/puppet/face/help.rb +29 -3
  29. data/lib/puppet/face/module/search.rb +5 -0
  30. data/lib/puppet/face/plugin.rb +2 -2
  31. data/lib/puppet/feature/base.rb +1 -1
  32. data/lib/puppet/file_serving/http_metadata.rb +14 -2
  33. data/lib/puppet/file_serving/metadata.rb +4 -1
  34. data/lib/puppet/file_serving/mount/locales.rb +1 -2
  35. data/lib/puppet/file_serving/mount/pluginfacts.rb +1 -2
  36. data/lib/puppet/file_serving/mount/plugins.rb +1 -2
  37. data/lib/puppet/file_serving/terminus_selector.rb +7 -8
  38. data/lib/puppet/file_system/file_impl.rb +17 -13
  39. data/lib/puppet/file_system/uniquefile.rb +12 -16
  40. data/lib/puppet/forge.rb +1 -1
  41. data/lib/puppet/forge/cache.rb +1 -1
  42. data/lib/puppet/forge/repository.rb +4 -7
  43. data/lib/puppet/functions/call.rb +1 -1
  44. data/lib/puppet/functions/eyaml_lookup_key.rb +13 -8
  45. data/lib/puppet/functions/filter.rb +1 -0
  46. data/lib/puppet/functions/lstrip.rb +4 -4
  47. data/lib/puppet/functions/reduce.rb +2 -4
  48. data/lib/puppet/functions/reverse_each.rb +1 -1
  49. data/lib/puppet/functions/rstrip.rb +4 -4
  50. data/lib/puppet/functions/step.rb +1 -1
  51. data/lib/puppet/functions/strip.rb +4 -4
  52. data/lib/puppet/gettext/config.rb +5 -5
  53. data/lib/puppet/gettext/module_translations.rb +4 -4
  54. data/lib/puppet/http.rb +3 -0
  55. data/lib/puppet/http/client.rb +263 -73
  56. data/lib/puppet/http/external_client.rb +90 -0
  57. data/lib/puppet/http/redirector.rb +43 -7
  58. data/lib/puppet/http/resolver.rb +46 -3
  59. data/lib/puppet/http/resolver/server_list.rb +76 -16
  60. data/lib/puppet/http/resolver/settings.rb +23 -3
  61. data/lib/puppet/http/resolver/srv.rb +29 -3
  62. data/lib/puppet/http/response.rb +87 -1
  63. data/lib/puppet/http/retry_after_handler.rb +39 -0
  64. data/lib/puppet/http/service.rb +97 -12
  65. data/lib/puppet/http/service/ca.rb +76 -14
  66. data/lib/puppet/http/service/compiler.rb +249 -16
  67. data/lib/puppet/http/service/file_server.rb +141 -20
  68. data/lib/puppet/http/service/report.rb +47 -17
  69. data/lib/puppet/http/session.rb +96 -7
  70. data/lib/puppet/indirector.rb +1 -1
  71. data/lib/puppet/indirector/catalog/rest.rb +34 -0
  72. data/lib/puppet/indirector/exec.rb +1 -1
  73. data/lib/puppet/indirector/facts/facter.rb +3 -3
  74. data/lib/puppet/indirector/facts/rest.rb +42 -0
  75. data/lib/puppet/indirector/file_bucket_file/rest.rb +48 -0
  76. data/lib/puppet/indirector/file_content/http.rb +5 -0
  77. data/lib/puppet/indirector/file_content/rest.rb +30 -0
  78. data/lib/puppet/indirector/file_metadata/http.rb +28 -8
  79. data/lib/puppet/indirector/file_metadata/rest.rb +52 -0
  80. data/lib/puppet/indirector/hiera.rb +4 -0
  81. data/lib/puppet/indirector/indirection.rb +1 -1
  82. data/lib/puppet/indirector/node/rest.rb +24 -0
  83. data/lib/puppet/indirector/report/processor.rb +2 -2
  84. data/lib/puppet/indirector/report/rest.rb +19 -0
  85. data/lib/puppet/indirector/report/yaml.rb +23 -0
  86. data/lib/puppet/indirector/request.rb +1 -1
  87. data/lib/puppet/indirector/rest.rb +12 -0
  88. data/lib/puppet/indirector/status/rest.rb +18 -0
  89. data/lib/puppet/loaders.rb +6 -0
  90. data/lib/puppet/metatype/manager.rb +80 -80
  91. data/lib/puppet/module.rb +1 -2
  92. data/lib/puppet/network/format_support.rb +2 -2
  93. data/lib/puppet/network/http/api/indirected_routes.rb +1 -1
  94. data/lib/puppet/network/http/api/master/v3/environment.rb +3 -0
  95. data/lib/puppet/network/http/base_pool.rb +7 -2
  96. data/lib/puppet/network/http/compression.rb +7 -0
  97. data/lib/puppet/network/http/connection.rb +2 -0
  98. data/lib/puppet/network/http/connection_adapter.rb +184 -0
  99. data/lib/puppet/network/http/nocache_pool.rb +1 -0
  100. data/lib/puppet/network/http/pool.rb +8 -5
  101. data/lib/puppet/network/http/route.rb +2 -2
  102. data/lib/puppet/network/http_pool.rb +2 -1
  103. data/lib/puppet/node/environment.rb +22 -5
  104. data/lib/puppet/pal/catalog_compiler.rb +5 -0
  105. data/lib/puppet/pal/pal_impl.rb +30 -31
  106. data/lib/puppet/parameter.rb +1 -1
  107. data/lib/puppet/parser/ast/leaf.rb +5 -5
  108. data/lib/puppet/parser/ast/pops_bridge.rb +0 -4
  109. data/lib/puppet/parser/compiler.rb +43 -33
  110. data/lib/puppet/parser/compiler/catalog_validator/env_relationship_validator.rb +2 -0
  111. data/lib/puppet/parser/compiler/catalog_validator/site_validator.rb +2 -0
  112. data/lib/puppet/parser/environment_compiler.rb +4 -1
  113. data/lib/puppet/parser/functions.rb +18 -9
  114. data/lib/puppet/parser/functions/create_resources.rb +11 -7
  115. data/lib/puppet/parser/functions/filter.rb +1 -0
  116. data/lib/puppet/parser/resource.rb +3 -2
  117. data/lib/puppet/parser/resource/param.rb +6 -0
  118. data/lib/puppet/parser/type_loader.rb +2 -2
  119. data/lib/puppet/pops/adaptable.rb +7 -13
  120. data/lib/puppet/pops/adapters.rb +8 -4
  121. data/lib/puppet/pops/evaluator/evaluator_impl.rb +5 -5
  122. data/lib/puppet/pops/issues.rb +5 -0
  123. data/lib/puppet/pops/loader/runtime3_type_loader.rb +4 -2
  124. data/lib/puppet/pops/loaders.rb +24 -15
  125. data/lib/puppet/pops/lookup/context.rb +1 -1
  126. data/lib/puppet/pops/lookup/hiera_config.rb +14 -1
  127. data/lib/puppet/pops/resource/resource_type_impl.rb +2 -0
  128. data/lib/puppet/pops/types/iterable.rb +34 -8
  129. data/lib/puppet/pops/validation/checker4_0.rb +29 -15
  130. data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -0
  131. data/lib/puppet/provider/file/windows.rb +1 -1
  132. data/lib/puppet/provider/group/groupadd.rb +9 -4
  133. data/lib/puppet/provider/group/windows_adsi.rb +3 -3
  134. data/lib/puppet/provider/package/aix.rb +17 -2
  135. data/lib/puppet/provider/package/apt.rb +98 -1
  136. data/lib/puppet/provider/package/aptitude.rb +1 -1
  137. data/lib/puppet/provider/package/dnfmodule.rb +61 -14
  138. data/lib/puppet/provider/package/gem.rb +45 -9
  139. data/lib/puppet/provider/package/pacman.rb +2 -5
  140. data/lib/puppet/provider/package/pip.rb +143 -48
  141. data/lib/puppet/provider/package/pip3.rb +0 -2
  142. data/lib/puppet/provider/package/pkgdmg.rb +1 -1
  143. data/lib/puppet/provider/package/pkgng.rb +16 -4
  144. data/lib/puppet/provider/package/portage.rb +2 -2
  145. data/lib/puppet/provider/package/puppet_gem.rb +11 -2
  146. data/lib/puppet/provider/package/rpm.rb +6 -213
  147. data/lib/puppet/provider/package/yum.rb +100 -20
  148. data/lib/puppet/provider/package/zypper.rb +62 -1
  149. data/lib/puppet/provider/service/systemd.rb +22 -4
  150. data/lib/puppet/provider/service/windows.rb +23 -7
  151. data/lib/puppet/provider/user/aix.rb +1 -1
  152. data/lib/puppet/provider/user/user_role_add.rb +1 -1
  153. data/lib/puppet/provider/user/useradd.rb +16 -5
  154. data/lib/puppet/provider/user/windows_adsi.rb +18 -1
  155. data/lib/puppet/reports/http.rb +15 -9
  156. data/lib/puppet/resource.rb +2 -1
  157. data/lib/puppet/resource/type.rb +8 -0
  158. data/lib/puppet/resource/type_collection.rb +20 -16
  159. data/lib/puppet/runtime.rb +31 -1
  160. data/lib/puppet/settings.rb +3 -1
  161. data/lib/puppet/settings/http_extra_headers_setting.rb +25 -0
  162. data/lib/puppet/ssl.rb +1 -0
  163. data/lib/puppet/ssl/host.rb +4 -4
  164. data/lib/puppet/ssl/oids.rb +1 -0
  165. data/lib/puppet/ssl/ssl_context.rb +2 -2
  166. data/lib/puppet/ssl/ssl_provider.rb +20 -1
  167. data/lib/puppet/ssl/state_machine.rb +81 -35
  168. data/lib/puppet/ssl/validator/default_validator.rb +1 -1
  169. data/lib/puppet/ssl/verifier_adapter.rb +9 -1
  170. data/lib/puppet/test/test_helper.rb +21 -14
  171. data/lib/puppet/transaction.rb +2 -2
  172. data/lib/puppet/transaction/persistence.rb +1 -1
  173. data/lib/puppet/transaction/report.rb +3 -3
  174. data/lib/puppet/trusted_external.rb +29 -1
  175. data/lib/puppet/type.rb +21 -8
  176. data/lib/puppet/type/file.rb +51 -13
  177. data/lib/puppet/type/file/checksum.rb +4 -4
  178. data/lib/puppet/type/file/source.rb +75 -64
  179. data/lib/puppet/type/notify.rb +2 -2
  180. data/lib/puppet/type/package.rb +41 -3
  181. data/lib/puppet/type/service.rb +59 -8
  182. data/lib/puppet/type/user.rb +19 -29
  183. data/lib/puppet/util.rb +41 -3
  184. data/lib/puppet/util/at_fork.rb +1 -1
  185. data/lib/puppet/util/autoload.rb +13 -25
  186. data/lib/puppet/util/character_encoding.rb +9 -5
  187. data/lib/puppet/util/checksums.rb +19 -4
  188. data/lib/puppet/util/execution.rb +2 -2
  189. data/lib/puppet/util/fileparsing.rb +2 -2
  190. data/lib/puppet/util/instance_loader.rb +14 -10
  191. data/lib/puppet/util/log/destinations.rb +1 -10
  192. data/lib/puppet/util/package/version/debian.rb +175 -0
  193. data/lib/puppet/util/package/version/gem.rb +15 -0
  194. data/lib/puppet/util/package/version/pip.rb +167 -0
  195. data/lib/puppet/util/package/version/range.rb +53 -0
  196. data/lib/puppet/util/package/version/range/eq.rb +14 -0
  197. data/lib/puppet/util/package/version/range/gt.rb +14 -0
  198. data/lib/puppet/util/package/version/range/gt_eq.rb +14 -0
  199. data/lib/puppet/util/package/version/range/lt.rb +14 -0
  200. data/lib/puppet/util/package/version/range/lt_eq.rb +14 -0
  201. data/lib/puppet/util/package/version/range/min_max.rb +21 -0
  202. data/lib/puppet/util/package/version/range/simple.rb +11 -0
  203. data/lib/puppet/util/package/version/rpm.rb +73 -0
  204. data/lib/puppet/util/pidlock.rb +13 -7
  205. data/lib/puppet/util/platform.rb +5 -0
  206. data/lib/puppet/util/provider_features.rb +1 -1
  207. data/lib/puppet/util/reference.rb +1 -1
  208. data/lib/puppet/util/rpm_compare.rb +193 -0
  209. data/lib/puppet/util/windows.rb +1 -0
  210. data/lib/puppet/util/windows/adsi.rb +2 -2
  211. data/lib/puppet/util/windows/api_types.rb +60 -33
  212. data/lib/puppet/util/windows/eventlog.rb +1 -6
  213. data/lib/puppet/util/windows/monkey_patches/dir.rb +40 -0
  214. data/lib/puppet/util/windows/principal.rb +8 -6
  215. data/lib/puppet/util/windows/process.rb +15 -14
  216. data/lib/puppet/util/windows/registry.rb +11 -11
  217. data/lib/puppet/util/windows/security.rb +5 -4
  218. data/lib/puppet/util/windows/service.rb +43 -26
  219. data/lib/puppet/util/windows/sid.rb +3 -3
  220. data/lib/puppet/util/windows/user.rb +242 -8
  221. data/lib/puppet/version.rb +1 -1
  222. data/locales/puppet.pot +641 -511
  223. data/man/man5/puppet.conf.5 +75 -10
  224. data/man/man8/puppet-agent.8 +7 -7
  225. data/man/man8/puppet-apply.8 +1 -1
  226. data/man/man8/puppet-catalog.8 +1 -1
  227. data/man/man8/puppet-config.8 +1 -1
  228. data/man/man8/puppet-describe.8 +1 -1
  229. data/man/man8/puppet-device.8 +2 -2
  230. data/man/man8/puppet-doc.8 +1 -1
  231. data/man/man8/puppet-epp.8 +1 -1
  232. data/man/man8/puppet-facts.8 +1 -1
  233. data/man/man8/puppet-filebucket.8 +17 -2
  234. data/man/man8/puppet-generate.8 +1 -1
  235. data/man/man8/puppet-help.8 +6 -3
  236. data/man/man8/puppet-key.8 +1 -1
  237. data/man/man8/puppet-lookup.8 +2 -2
  238. data/man/man8/puppet-man.8 +1 -1
  239. data/man/man8/puppet-module.8 +4 -1
  240. data/man/man8/puppet-node.8 +1 -1
  241. data/man/man8/puppet-parser.8 +1 -1
  242. data/man/man8/puppet-plugin.8 +1 -1
  243. data/man/man8/puppet-report.8 +1 -1
  244. data/man/man8/puppet-resource.8 +1 -1
  245. data/man/man8/puppet-script.8 +1 -1
  246. data/man/man8/puppet-ssl.8 +2 -2
  247. data/man/man8/puppet-status.8 +1 -1
  248. data/man/man8/puppet.8 +2 -2
  249. data/spec/fixtures/integration/application/apply/environments/spec/modules/amod/lib/puppet/provider/applytest/applytest.rb +2 -0
  250. data/spec/fixtures/integration/application/apply/environments/spec/modules/amod/lib/puppet/type/applytest.rb +25 -0
  251. data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +67 -0
  252. data/spec/fixtures/ssl/unknown-127.0.0.1.pem +48 -0
  253. data/spec/fixtures/ssl/unknown-ca-key.pem +67 -0
  254. data/spec/fixtures/ssl/unknown-ca.pem +59 -0
  255. data/spec/fixtures/unit/forge/bacula-releases.json +128 -0
  256. data/spec/fixtures/unit/forge/bacula.tar.gz +0 -0
  257. data/spec/fixtures/unit/provider/package/dnfmodule/{dnf-module-list-installed.txt → dnf-module-list.txt} +8 -0
  258. data/spec/fixtures/unit/provider/package/pkgng/pkg.version +2 -0
  259. data/spec/fixtures/unit/provider/package/yum/yum-check-update-subscription-manager.txt +9 -0
  260. data/spec/fixtures/unit/provider/package/zypper/zypper-search-uninstalled.out +13 -0
  261. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services +9 -0
  262. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_fetch_if_not_on_the_local_disk.yml +1 -67
  263. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_not_update_if_content_on_disk_is_up-to-date.yml +1 -69
  264. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_update_if_content_differs_on_disk.yml +1 -69
  265. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_mtime_is_older_on_disk.yml +1 -67
  266. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_no_header_specified.yml +1 -65
  267. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_not_on_the_local_disk.yml +1 -67
  268. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_not_update_if_mtime_is_newer_on_disk.yml +1 -67
  269. data/spec/integration/application/agent_spec.rb +475 -0
  270. data/spec/integration/application/apply_spec.rb +279 -150
  271. data/spec/integration/application/config_spec.rb +74 -0
  272. data/spec/integration/application/doc_spec.rb +16 -6
  273. data/spec/integration/application/filebucket_spec.rb +239 -0
  274. data/spec/integration/application/help_spec.rb +42 -0
  275. data/spec/integration/application/lookup_spec.rb +13 -0
  276. data/spec/integration/application/module_spec.rb +68 -0
  277. data/spec/integration/application/plugin_spec.rb +123 -0
  278. data/spec/integration/data_binding_spec.rb +82 -0
  279. data/spec/integration/defaults_spec.rb +1 -2
  280. data/spec/integration/directory_environments_spec.rb +17 -17
  281. data/spec/integration/http/client_spec.rb +47 -37
  282. data/spec/integration/indirector/facts/facter_spec.rb +8 -6
  283. data/spec/integration/indirector/report/yaml.rb +83 -0
  284. data/spec/integration/network/http_pool_spec.rb +93 -20
  285. data/spec/integration/node/environment_spec.rb +15 -0
  286. data/spec/integration/parser/compiler_spec.rb +11 -0
  287. data/spec/integration/type/file_spec.rb +1 -1
  288. data/spec/integration/util/execution_spec.rb +22 -0
  289. data/spec/integration/util/windows/adsi_spec.rb +6 -1
  290. data/spec/integration/util/windows/monkey_patches/dir_spec.rb +11 -0
  291. data/spec/integration/util/windows/process_spec.rb +26 -32
  292. data/spec/integration/util/windows/registry_spec.rb +7 -7
  293. data/spec/integration/util/windows/user_spec.rb +47 -5
  294. data/spec/integration/util_spec.rb +7 -33
  295. data/spec/lib/puppet/test_ca.rb +2 -2
  296. data/spec/lib/puppet_spec/https.rb +16 -7
  297. data/spec/lib/puppet_spec/matchers.rb +0 -80
  298. data/spec/lib/puppet_spec/puppetserver.rb +127 -0
  299. data/spec/shared_contexts/https.rb +29 -0
  300. data/spec/unit/agent_spec.rb +80 -26
  301. data/spec/unit/application/agent_spec.rb +12 -9
  302. data/spec/unit/application/describe_spec.rb +88 -50
  303. data/spec/unit/application/device_spec.rb +2 -2
  304. data/spec/unit/application/face_base_spec.rb +6 -4
  305. data/spec/unit/application/facts_spec.rb +39 -10
  306. data/spec/unit/application/filebucket_spec.rb +22 -2
  307. data/spec/unit/application/man_spec.rb +52 -0
  308. data/spec/unit/application/resource_spec.rb +3 -1
  309. data/spec/unit/application/ssl_spec.rb +15 -2
  310. data/spec/unit/configurer/downloader_spec.rb +10 -0
  311. data/spec/unit/configurer/fact_handler_spec.rb +4 -4
  312. data/spec/unit/configurer/plugin_handler_spec.rb +36 -19
  313. data/spec/unit/configurer_spec.rb +64 -46
  314. data/spec/unit/confine_spec.rb +2 -1
  315. data/spec/unit/context/trusted_information_spec.rb +25 -2
  316. data/spec/unit/daemon_spec.rb +5 -64
  317. data/spec/unit/defaults_spec.rb +24 -1
  318. data/spec/unit/environments_spec.rb +8 -0
  319. data/spec/unit/face/config_spec.rb +3 -1
  320. data/spec/unit/face/module/search_spec.rb +17 -0
  321. data/spec/unit/face/plugin_spec.rb +12 -10
  322. data/spec/unit/file_serving/http_metadata_spec.rb +37 -14
  323. data/spec/unit/file_serving/mount/locales_spec.rb +2 -2
  324. data/spec/unit/file_serving/mount/pluginfacts_spec.rb +2 -2
  325. data/spec/unit/file_serving/mount/plugins_spec.rb +2 -2
  326. data/spec/unit/file_serving/terminus_selector_spec.rb +45 -26
  327. data/spec/unit/file_system/uniquefile_spec.rb +29 -0
  328. data/spec/unit/file_system_spec.rb +10 -0
  329. data/spec/unit/functions/lookup_spec.rb +13 -0
  330. data/spec/unit/http/client_spec.rb +321 -36
  331. data/spec/unit/http/external_client_spec.rb +201 -0
  332. data/spec/unit/http/resolver_spec.rb +34 -3
  333. data/spec/unit/http/response_spec.rb +75 -0
  334. data/spec/unit/http/service/ca_spec.rb +53 -12
  335. data/spec/unit/http/service/compiler_spec.rb +332 -28
  336. data/spec/unit/http/service/file_server_spec.rb +100 -12
  337. data/spec/unit/http/service/report_spec.rb +19 -9
  338. data/spec/unit/http/service_spec.rb +94 -6
  339. data/spec/unit/http/session_spec.rb +159 -8
  340. data/spec/unit/indirector/catalog/compiler_spec.rb +1 -0
  341. data/spec/unit/indirector/catalog/rest_spec.rb +59 -2
  342. data/spec/unit/indirector/facts/rest_spec.rb +79 -24
  343. data/spec/unit/indirector/file_bucket_file/rest_spec.rb +82 -2
  344. data/spec/unit/indirector/file_content/rest_spec.rb +53 -2
  345. data/spec/unit/indirector/file_metadata/http_spec.rb +194 -0
  346. data/spec/unit/indirector/file_metadata/rest_spec.rb +110 -2
  347. data/spec/unit/indirector/node/rest_spec.rb +57 -2
  348. data/spec/unit/indirector/report/rest_spec.rb +58 -51
  349. data/spec/unit/indirector/request_spec.rb +1 -1
  350. data/spec/unit/indirector/resource/ral_spec.rb +7 -8
  351. data/spec/unit/indirector/rest_spec.rb +13 -0
  352. data/spec/unit/indirector/status/rest_spec.rb +43 -2
  353. data/spec/unit/interface_spec.rb +3 -3
  354. data/spec/unit/module_tool/tar/mini_spec.rb +20 -0
  355. data/spec/unit/network/format_support_spec.rb +3 -2
  356. data/spec/unit/network/http/api/indirected_routes_spec.rb +2 -1
  357. data/spec/unit/network/http/connection_spec.rb +552 -190
  358. data/spec/unit/network/http/nocache_pool_spec.rb +22 -0
  359. data/spec/unit/network/http/pool_spec.rb +59 -13
  360. data/spec/unit/network/http_pool_spec.rb +63 -57
  361. data/spec/unit/network/http_spec.rb +1 -1
  362. data/spec/unit/node/environment_spec.rb +33 -0
  363. data/spec/unit/parser/ast/block_expression_spec.rb +1 -1
  364. data/spec/unit/parser/environment_compiler_spec.rb +7 -0
  365. data/spec/unit/parser/scope_spec.rb +1 -1
  366. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +15 -1
  367. data/spec/unit/pops/loaders/loaders_spec.rb +71 -1
  368. data/spec/unit/pops/lookup/lookup_spec.rb +25 -0
  369. data/spec/unit/pops/types/type_calculator_spec.rb +1 -11
  370. data/spec/unit/provider/group/groupadd_spec.rb +22 -8
  371. data/spec/unit/provider/group/windows_adsi_spec.rb +43 -10
  372. data/spec/unit/provider/package/aix_spec.rb +29 -0
  373. data/spec/unit/provider/package/apt_spec.rb +107 -0
  374. data/spec/unit/provider/package/aptitude_spec.rb +1 -0
  375. data/spec/unit/provider/package/dnfmodule_spec.rb +54 -15
  376. data/spec/unit/provider/package/gem_spec.rb +40 -0
  377. data/spec/unit/provider/package/pacman_spec.rb +6 -21
  378. data/spec/unit/provider/package/pip_spec.rb +68 -19
  379. data/spec/unit/provider/package/pkgdmg_spec.rb +1 -1
  380. data/spec/unit/provider/package/pkgng_spec.rb +38 -0
  381. data/spec/unit/provider/package/portage_spec.rb +5 -0
  382. data/spec/unit/provider/package/puppet_gem_spec.rb +12 -1
  383. data/spec/unit/provider/package/rpm_spec.rb +0 -212
  384. data/spec/unit/provider/package/yum_spec.rb +243 -1
  385. data/spec/unit/provider/package/zypper_spec.rb +98 -0
  386. data/spec/unit/provider/service/init_spec.rb +42 -0
  387. data/spec/unit/provider/service/openbsd_spec.rb +9 -0
  388. data/spec/unit/provider/service/openwrt_spec.rb +1 -0
  389. data/spec/unit/provider/service/redhat_spec.rb +9 -0
  390. data/spec/unit/provider/service/systemd_spec.rb +93 -18
  391. data/spec/unit/provider/service/windows_spec.rb +50 -14
  392. data/spec/unit/provider/user/openbsd_spec.rb +1 -0
  393. data/spec/unit/provider/user/useradd_spec.rb +30 -16
  394. data/spec/unit/provider/user/windows_adsi_spec.rb +85 -3
  395. data/spec/unit/puppet_pal_2pec.rb +11 -0
  396. data/spec/unit/puppet_pal_catalog_spec.rb +43 -0
  397. data/spec/unit/puppet_spec.rb +33 -0
  398. data/spec/unit/reports/http_spec.rb +70 -52
  399. data/spec/unit/reports/store_spec.rb +17 -13
  400. data/spec/unit/resource_spec.rb +3 -3
  401. data/spec/unit/settings/autosign_setting_spec.rb +1 -1
  402. data/spec/unit/settings/http_extra_headers_spec.rb +64 -0
  403. data/spec/unit/ssl/host_spec.rb +4 -2
  404. data/spec/unit/ssl/oids_spec.rb +1 -0
  405. data/spec/unit/ssl/ssl_provider_spec.rb +69 -43
  406. data/spec/unit/ssl/state_machine_spec.rb +99 -13
  407. data/spec/unit/test/test_helper_spec.rb +17 -0
  408. data/spec/unit/transaction/persistence_spec.rb +15 -0
  409. data/spec/unit/transaction/report_spec.rb +5 -1
  410. data/spec/unit/transaction_spec.rb +0 -2
  411. data/spec/unit/type/file/ensure_spec.rb +1 -2
  412. data/spec/unit/type/file/source_spec.rb +89 -38
  413. data/spec/unit/type/file_spec.rb +122 -96
  414. data/spec/unit/type/service_spec.rb +218 -8
  415. data/spec/unit/type/user_spec.rb +32 -3
  416. data/spec/unit/type_spec.rb +50 -0
  417. data/spec/unit/util/at_fork_spec.rb +3 -2
  418. data/spec/unit/util/autoload_spec.rb +2 -1
  419. data/spec/unit/util/character_encoding_spec.rb +4 -4
  420. data/spec/unit/util/checksums_spec.rb +16 -0
  421. data/spec/unit/util/command_line_spec.rb +11 -6
  422. data/spec/unit/util/log/destinations_spec.rb +1 -29
  423. data/spec/unit/util/package/version/debian_spec.rb +83 -0
  424. data/spec/unit/util/package/version/pip_spec.rb +464 -0
  425. data/spec/unit/util/package/version/range_spec.rb +175 -0
  426. data/spec/unit/util/package/version/rpm_spec.rb +121 -0
  427. data/spec/unit/util/pidlock_spec.rb +102 -54
  428. data/spec/unit/util/rpm_compare_spec.rb +196 -0
  429. data/spec/unit/util/windows/adsi_spec.rb +4 -4
  430. data/spec/unit/util/windows/api_types_spec.rb +104 -40
  431. data/spec/unit/util/windows/service_spec.rb +4 -4
  432. data/spec/unit/util/windows/sid_spec.rb +2 -2
  433. data/spec/unit/util_spec.rb +3 -3
  434. data/spec/unit/x509/cert_provider_spec.rb +1 -1
  435. data/tasks/generate_cert_fixtures.rake +15 -1
  436. data/tasks/manpages.rake +5 -35
  437. metadata +84 -52
  438. data/COMMITTERS.md +0 -244
  439. data/spec/integration/faces/config_spec.rb +0 -91
  440. data/spec/integration/faces/documentation_spec.rb +0 -57
  441. data/spec/integration/faces/plugin_spec.rb +0 -61
  442. data/spec/integration/file_bucket/file_spec.rb +0 -50
  443. data/spec/integration/file_serving/content_spec.rb +0 -7
  444. data/spec/integration/file_serving/fileset_spec.rb +0 -12
  445. data/spec/integration/file_serving/metadata_spec.rb +0 -8
  446. data/spec/integration/file_serving/terminus_helper_spec.rb +0 -20
  447. data/spec/integration/file_system/uniquefile_spec.rb +0 -26
  448. data/spec/integration/module_tool/forge_spec.rb +0 -64
  449. data/spec/integration/module_tool/tar/mini_spec.rb +0 -28
  450. data/spec/integration/provider/service/init_spec.rb +0 -48
  451. data/spec/integration/provider/service/systemd_spec.rb +0 -25
  452. data/spec/integration/provider/service/windows_spec.rb +0 -50
  453. data/spec/integration/reference/providers_spec.rb +0 -21
  454. data/spec/integration/reports_spec.rb +0 -13
  455. data/spec/integration/ssl/certificate_request_spec.rb +0 -44
  456. data/spec/integration/ssl/host_spec.rb +0 -72
  457. data/spec/integration/ssl/key_spec.rb +0 -99
  458. data/spec/integration/test/test_helper_spec.rb +0 -31
  459. data/spec/shared_behaviours/file_serving_model.rb +0 -51
  460. data/spec/unit/face/man_spec.rb +0 -25
  461. data/spec/unit/man_spec.rb +0 -31
@@ -52,13 +52,13 @@ describe Puppet::FileServing::Mount::Plugins do
52
52
  expect(@mount.search("foo/bar", @request)).to eq(["/"])
53
53
  end
54
54
 
55
- it "should return nil if no modules can be found that have plugins and modulepath is invalid" do
55
+ it "should return the default search module path if no modules can be found that have plugins and modulepath is invalid" do
56
56
  mod = double('module')
57
57
  allow(mod).to receive(:plugins?).and_return(false)
58
58
 
59
59
  allow(@environment).to receive(:modules).and_return([])
60
60
  allow(@environment).to receive(:modulepath).and_return([])
61
- expect(@mount.search("foo/bar", @request)).to be_nil
61
+ expect(@mount.search("foo/bar", @request)).to eq([Puppet[:codedir]])
62
62
  end
63
63
 
64
64
  it "should return the plugin paths for each module that has plugins" do
@@ -3,62 +3,81 @@ require 'spec_helper'
3
3
  require 'puppet/file_serving/terminus_selector'
4
4
 
5
5
  describe Puppet::FileServing::TerminusSelector do
6
- before do
7
- @object = Object.new
8
- @object.extend(Puppet::FileServing::TerminusSelector)
6
+ class TestSelector
7
+ include Puppet::FileServing::TerminusSelector
8
+ end
9
9
 
10
- @request = double('request', :key => "mymod/myfile", :options => {:node => "whatever"}, :server => nil, :protocol => nil)
10
+ def create_request(key)
11
+ Puppet::Indirector::Request.new(:indirection_name, :find, key, nil, {node: 'whatever'})
11
12
  end
12
13
 
14
+ subject { TestSelector.new }
15
+
13
16
  describe "when being used to select termini" do
14
17
  it "should return :file if the request key is fully qualified" do
15
- expect(@request).to receive(:key).and_return(File.expand_path('/foo'))
16
- expect(@object.select(@request)).to eq(:file)
18
+ request = create_request(File.expand_path('/foo'))
19
+
20
+ expect(subject.select(request)).to eq(:file)
21
+ end
22
+
23
+ it "should return :file_server if the request key is relative" do
24
+ request = create_request('modules/my_module/path/to_file')
25
+
26
+ expect(subject.select(request)).to eq(:file_server)
17
27
  end
18
28
 
19
29
  it "should return :file if the URI protocol is set to 'file'" do
20
- expect(@request).to receive(:protocol).and_return("file")
21
- expect(@object.select(@request)).to eq(:file)
30
+ request = create_request(Puppet::Util.path_to_uri(File.expand_path("/foo")).to_s)
31
+
32
+ expect(subject.select(request)).to eq(:file)
22
33
  end
23
34
 
24
35
  it "should return :http if the URI protocol is set to 'http'" do
25
- expect(@request).to receive(:protocol).and_return("http")
26
- expect(@object.select(@request)).to eq :http
36
+ request = create_request("http://www.example.com")
37
+
38
+ expect(subject.select(request)).to eq(:http)
27
39
  end
28
40
 
29
41
  it "should return :http if the URI protocol is set to 'https'" do
30
- expect(@request).to receive(:protocol).and_return("https")
31
- expect(@object.select(@request)).to eq :http
42
+ request = create_request("https://www.example.com")
43
+
44
+ expect(subject.select(request)).to eq(:http)
45
+ end
46
+
47
+ it "should return :http if the path starts with a double slash" do
48
+ request = create_request("https://www.example.com//index.html")
49
+
50
+ expect(subject.select(request)).to eq(:http)
32
51
  end
33
52
 
34
53
  it "should fail when a protocol other than :puppet, :http(s) or :file is used" do
35
- allow(@request).to receive(:protocol).and_return("ftp")
36
- expect { @object.select(@request) }.to raise_error(ArgumentError)
54
+ request = create_request("ftp://ftp.example.com")
55
+
56
+ expect {
57
+ subject.select(request)
58
+ }.to raise_error(ArgumentError, /URI protocol 'ftp' is not currently supported for file serving/)
37
59
  end
38
60
 
39
61
  describe "and the protocol is 'puppet'" do
40
- before do
41
- allow(@request).to receive(:protocol).and_return("puppet")
42
- end
43
-
44
62
  it "should choose :rest when a server is specified" do
45
- allow(@request).to receive(:protocol).and_return("puppet")
46
- expect(@request).to receive(:server).and_return("foo")
47
- expect(@object.select(@request)).to eq(:rest)
63
+ request = create_request("puppet://puppetserver.example.com")
64
+
65
+ expect(subject.select(request)).to eq(:rest)
48
66
  end
49
67
 
50
68
  # This is so a given file location works when bootstrapping with no server.
51
69
  it "should choose :rest when default_file_terminus is rest" do
52
- allow(@request).to receive(:protocol).and_return("puppet")
53
70
  Puppet[:server] = 'localhost'
54
- expect(@object.select(@request)).to eq(:rest)
71
+ request = create_request("puppet:///plugins")
72
+
73
+ expect(subject.select(request)).to eq(:rest)
55
74
  end
56
75
 
57
76
  it "should choose :file_server when default_file_terminus is file_server and no server is specified on the request" do
58
- expect(@request).to receive(:protocol).and_return("puppet")
59
- expect(@request).to receive(:server).and_return(nil)
60
77
  Puppet[:default_file_terminus] = 'file_server'
61
- expect(@object.select(@request)).to eq(:file_server)
78
+ request = create_request("puppet:///plugins")
79
+
80
+ expect(subject.select(request)).to eq(:file_server)
62
81
  end
63
82
  end
64
83
  end
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Puppet::FileSystem::Uniquefile do
4
+ include PuppetSpec::Files
5
+
4
6
  it "makes the name of the file available" do
5
7
  Puppet::FileSystem::Uniquefile.open_tmp('foo') do |file|
6
8
  expect(file.path).to match(/foo/)
@@ -73,6 +75,33 @@ describe Puppet::FileSystem::Uniquefile do
73
75
  Puppet::FileSystem::Uniquefile.open_tmp('foo') { |tmp| }
74
76
  end
75
77
 
78
+ it "reports when a parent directory does not exist" do
79
+ dir = tmpdir('uniquefile')
80
+ lock = File.join(dir, 'path', 'to', 'lock')
81
+
82
+ expect {
83
+ Puppet::FileSystem::Uniquefile.open_tmp(lock) { |tmp| }
84
+ }.to raise_error(Errno::ENOENT, %r{No such file or directory - A directory component in .* does not exist or is a dangling symbolic link})
85
+ end
86
+
87
+ it "should use UTF8 characters in TMP,TEMP,TMPDIR environment variable", :if => Puppet::Util::Platform.windows? do
88
+ rune_utf8 = "\u16A0\u16C7\u16BB\u16EB\u16D2\u16E6\u16A6\u16EB\u16A0\u16B1\u16A9\u16A0\u16A2\u16B1\u16EB\u16A0\u16C1\u16B1\u16AA\u16EB\u16B7\u16D6\u16BB\u16B9\u16E6\u16DA\u16B3\u16A2\u16D7"
89
+ temp_rune_utf8 = File.join(Dir.tmpdir, rune_utf8)
90
+ Puppet::FileSystem.mkpath(temp_rune_utf8)
91
+
92
+ # Set the temporary environment variables to the UTF8 temp path
93
+ Puppet::Util::Windows::Process.set_environment_variable('TMPDIR', temp_rune_utf8)
94
+ Puppet::Util::Windows::Process.set_environment_variable('TMP', temp_rune_utf8)
95
+ Puppet::Util::Windows::Process.set_environment_variable('TEMP', temp_rune_utf8)
96
+
97
+ # Create a unique file
98
+ filename = Puppet::FileSystem::Uniquefile.open_tmp('foo') do |file|
99
+ File.dirname(file.path)
100
+ end
101
+
102
+ expect(filename).to eq(temp_rune_utf8)
103
+ end
104
+
76
105
  context "Ruby 1.9.3 Tempfile tests" do
77
106
  # the remaining tests in this file are ported directly from the ruby 1.9.3 source,
78
107
  # since most of this file was ported from there
@@ -970,6 +970,16 @@ describe "Puppet::FileSystem" do
970
970
  mode = Puppet::FileSystem.stat(dest).mode
971
971
  expect(mode & 07777).to eq(0400)
972
972
  end
973
+
974
+ it 'preserves file ownership' do
975
+ allow(Puppet::FileSystem).to receive(:lstat)
976
+ .with(Puppet::FileSystem.pathname(dest))
977
+ .and_return(double(uid: 1, gid: 2))
978
+
979
+ expect(FileUtils).to receive(:chown).with(1, 2, /#{dest}/)
980
+
981
+ Puppet::FileSystem.replace_file(dest, 0644) { |f| f.write(content) }
982
+ end
973
983
  end
974
984
 
975
985
  context 'on windows', if: Puppet::Util::Platform.windows? do
@@ -3082,6 +3082,19 @@ describe "The lookup function" do
3082
3082
 
3083
3083
  let(:env_data) { data_files }
3084
3084
 
3085
+ context 'with unencryptable eyaml' do
3086
+ let(:data_files) do
3087
+ {
3088
+ 'common.eyaml' => <<-YAML.unindent
3089
+ key_with_invalid_eyaml: ENC[PKCS7,INVALID]
3090
+ YAML
3091
+ }
3092
+ end
3093
+
3094
+ it 'fails and reports error with ENC value, key being looked up and filename' do
3095
+ expect { lookup('key_with_invalid_eyaml') }.to raise_error(Puppet::DataBinding::LookupError, /hiera-eyaml backend error decrypting ENC\[PKCS7,INVALID\] when looking up key_with_invalid_eyaml in .*common\.eyaml\. Error was/)
3096
+ end
3097
+ end
3085
3098
  context 'and a module using eyaml with different options' do
3086
3099
 
3087
3100
  let(:private_module_key) do
@@ -1,10 +1,11 @@
1
1
  require 'spec_helper'
2
- require 'webmock/rspec'
3
2
  require 'puppet/http'
4
3
 
5
4
  describe Puppet::HTTP::Client do
6
5
  let(:uri) { URI.parse('https://www.example.com') }
7
- let(:client) { described_class.new }
6
+ let(:puppet_context) { Puppet::SSL::SSLContext.new }
7
+ let(:system_context) { Puppet::SSL::SSLContext.new }
8
+ let(:client) { described_class.new(ssl_context: puppet_context, system_ssl_context: system_context) }
8
9
  let(:credentials) { ['user', 'pass'] }
9
10
 
10
11
  it 'creates unique sessions' do
@@ -45,6 +46,46 @@ describe Puppet::HTTP::Client do
45
46
  client.connect(uri)
46
47
  }.to raise_error(Puppet::HTTP::ConnectionError, %r{^Request to https://www.example.com timed out connect operation after .* seconds})
47
48
  end
49
+
50
+ it 'connects using the default ssl context' do
51
+ expect(client.pool).to receive(:with_connection) do |_, verifier|
52
+ expect(verifier.ssl_context).to equal(puppet_context)
53
+ end
54
+
55
+ client.connect(uri)
56
+ end
57
+
58
+ it 'connects using a specified ssl context' do
59
+ other_context = Puppet::SSL::SSLContext.new
60
+
61
+ expect(client.pool).to receive(:with_connection) do |_, verifier|
62
+ expect(verifier.ssl_context).to equal(other_context)
63
+ end
64
+
65
+ client.connect(uri, options: {ssl_context: other_context})
66
+ end
67
+
68
+ it 'connects using the system store' do
69
+ expect(client.pool).to receive(:with_connection) do |_, verifier|
70
+ expect(verifier.ssl_context).to equal(system_context)
71
+ end
72
+
73
+ client.connect(uri, options: {include_system_store: true})
74
+ end
75
+
76
+ it 'does not create a verifier for HTTP connections' do
77
+ expect(client.pool).to receive(:with_connection) do |_, verifier|
78
+ expect(verifier).to be_nil
79
+ end
80
+
81
+ client.connect(URI.parse('http://www.example.com'))
82
+ end
83
+
84
+ it 'raises an HTTPError if both are specified' do
85
+ expect {
86
+ client.connect(uri, options: {ssl_context: puppet_context, include_system_store: true})
87
+ }.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
88
+ end
48
89
  end
49
90
 
50
91
  context 'after connecting' do
@@ -75,10 +116,8 @@ describe Puppet::HTTP::Client do
75
116
 
76
117
  context "when closing" do
77
118
  it "closes all connections in the pool" do
78
- pool = double('pool')
79
- expect(pool).to receive(:close)
119
+ expect(client.pool).to receive(:close)
80
120
 
81
- client = described_class.new(pool: pool)
82
121
  client.close
83
122
  end
84
123
  end
@@ -138,6 +177,28 @@ describe Puppet::HTTP::Client do
138
177
 
139
178
  expect(io.string).to eq("abc")
140
179
  end
180
+
181
+ context 'when connecting' do
182
+ it 'uses a specified ssl context' do
183
+ stub_request(:get, uri).to_return(body: "abc")
184
+
185
+ other_context = Puppet::SSL::SSLContext.new
186
+
187
+ client.get(uri, options: {ssl_context: other_context})
188
+ end
189
+
190
+ it 'uses the system store' do
191
+ stub_request(:get, uri).to_return(body: "abc")
192
+
193
+ client.get(uri, options: {include_system_store: true})
194
+ end
195
+
196
+ it 'raises an HTTPError if both are specified' do
197
+ expect {
198
+ client.get(uri, options: {ssl_context: puppet_context, include_system_store: true})
199
+ }.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
200
+ end
201
+ end
141
202
  end
142
203
 
143
204
  context "for HEAD requests" do
@@ -173,6 +234,28 @@ describe Puppet::HTTP::Client do
173
234
 
174
235
  expect(client.head(uri).body).to eq("abc")
175
236
  end
237
+
238
+ context 'when connecting' do
239
+ it 'uses a specified ssl context' do
240
+ stub_request(:head, uri)
241
+
242
+ other_context = Puppet::SSL::SSLContext.new
243
+
244
+ client.head(uri, options: {ssl_context: other_context})
245
+ end
246
+
247
+ it 'uses the system store' do
248
+ stub_request(:head, uri)
249
+
250
+ client.head(uri, options: {include_system_store: true})
251
+ end
252
+
253
+ it 'raises an HTTPError if both are specified' do
254
+ expect {
255
+ client.head(uri, options: {ssl_context: puppet_context, include_system_store: true})
256
+ }.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
257
+ end
258
+ end
176
259
  end
177
260
 
178
261
  context "for PUT requests" do
@@ -182,25 +265,25 @@ describe Puppet::HTTP::Client do
182
265
  expect(request.headers).to_not include('X-Puppet-Profiling')
183
266
  end
184
267
 
185
- client.put(uri, content_type: 'text/plain', body: "")
268
+ client.put(uri, "", headers: {'Content-Type' => 'text/plain'})
186
269
  end
187
270
 
188
271
  it "stringifies keys and encodes values in the query" do
189
272
  stub_request(:put, "https://www.example.com").with(query: "foo=bar%3Dbaz")
190
273
 
191
- client.put(uri, params: {:foo => "bar=baz"}, content_type: 'text/plain', body: "")
274
+ client.put(uri, "", params: {:foo => "bar=baz"}, headers: {'Content-Type' => 'text/plain'})
192
275
  end
193
276
 
194
277
  it "includes custom headers" do
195
278
  stub_request(:put, "https://www.example.com").with(headers: { 'X-Foo' => 'Bar' })
196
279
 
197
- client.put(uri, headers: {'X-Foo' => 'Bar'}, content_type: 'text/plain', body: "")
280
+ client.put(uri, "", headers: {'X-Foo' => 'Bar', 'Content-Type' => 'text/plain'})
198
281
  end
199
282
 
200
283
  it "returns the response" do
201
284
  stub_request(:put, uri)
202
285
 
203
- response = client.put(uri, content_type: 'text/plain', body: "")
286
+ response = client.put(uri, "", headers: {'Content-Type' => 'text/plain'})
204
287
  expect(response).to be_an_instance_of(Puppet::HTTP::Response)
205
288
  expect(response).to be_success
206
289
  expect(response.code).to eq(200)
@@ -209,7 +292,41 @@ describe Puppet::HTTP::Client do
209
292
  it "sets content-length and content-type for the body" do
210
293
  stub_request(:put, uri).with(headers: {"Content-Length" => "5", "Content-Type" => "text/plain"})
211
294
 
212
- client.put(uri, content_type: 'text/plain', body: "hello")
295
+ client.put(uri, "hello", headers: {'Content-Type' => 'text/plain'})
296
+ end
297
+
298
+ it 'raises an ArgumentError if `body` is missing' do
299
+ expect {
300
+ client.put(uri, nil, headers: {'Content-Type' => 'text/plain'})
301
+ }.to raise_error(ArgumentError, /'put' requires a string 'body' argument/)
302
+ end
303
+
304
+ it 'raises an ArgumentError if `content_type` is missing from the headers hash' do
305
+ expect {
306
+ client.put(uri, '')
307
+ }.to raise_error(ArgumentError, /'put' requires a 'content-type' header/)
308
+ end
309
+
310
+ context 'when connecting' do
311
+ it 'uses a specified ssl context' do
312
+ stub_request(:put, uri)
313
+
314
+ other_context = Puppet::SSL::SSLContext.new
315
+
316
+ client.put(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {ssl_context: other_context})
317
+ end
318
+
319
+ it 'uses the system store' do
320
+ stub_request(:put, uri)
321
+
322
+ client.put(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {include_system_store: true})
323
+ end
324
+
325
+ it 'raises an HTTPError if both are specified' do
326
+ expect {
327
+ client.put(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {ssl_context: puppet_context, include_system_store: true})
328
+ }.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
329
+ end
213
330
  end
214
331
  end
215
332
 
@@ -217,25 +334,25 @@ describe Puppet::HTTP::Client do
217
334
  it "includes default HTTP headers" do
218
335
  stub_request(:post, uri).with(headers: {'X-Puppet-Version' => /./, 'User-Agent' => /./})
219
336
 
220
- client.post(uri, content_type: 'text/plain', body: "")
337
+ client.post(uri, "", headers: {'Content-Type' => 'text/plain'})
221
338
  end
222
339
 
223
340
  it "stringifies keys and encodes values in the query" do
224
341
  stub_request(:post, "https://www.example.com").with(query: "foo=bar%3Dbaz")
225
342
 
226
- client.post(uri, params: {:foo => "bar=baz"}, content_type: 'text/plain', body: "")
343
+ client.post(uri, "", params: {:foo => "bar=baz"}, headers: {'Content-Type' => 'text/plain'})
227
344
  end
228
345
 
229
346
  it "includes custom headers" do
230
347
  stub_request(:post, "https://www.example.com").with(headers: { 'X-Foo' => 'Bar' })
231
348
 
232
- client.post(uri, headers: {'X-Foo' => 'Bar'}, content_type: 'text/plain', body: "")
349
+ client.post(uri, "", headers: {'X-Foo' => 'Bar', 'Content-Type' => 'text/plain'})
233
350
  end
234
351
 
235
352
  it "returns the response" do
236
353
  stub_request(:post, uri)
237
354
 
238
- response = client.post(uri, content_type: 'text/plain', body: "")
355
+ response = client.post(uri, "", headers: {'Content-Type' => 'text/plain'})
239
356
  expect(response).to be_an_instance_of(Puppet::HTTP::Response)
240
357
  expect(response).to be_success
241
358
  expect(response.code).to eq(200)
@@ -244,14 +361,14 @@ describe Puppet::HTTP::Client do
244
361
  it "sets content-length and content-type for the body" do
245
362
  stub_request(:post, uri).with(headers: {"Content-Length" => "5", "Content-Type" => "text/plain"})
246
363
 
247
- client.post(uri, content_type: 'text/plain', body: "hello")
364
+ client.post(uri, "hello", headers: {'Content-Type' => 'text/plain'})
248
365
  end
249
366
 
250
367
  it "streams the response body when a block is given" do
251
368
  stub_request(:post, uri).to_return(body: "abc")
252
369
 
253
370
  io = StringIO.new
254
- client.post(uri, content_type: 'text/plain', body: "") do |response|
371
+ client.post(uri, "", headers: {'Content-Type' => 'text/plain'}) do |response|
255
372
  response.read_body do |data|
256
373
  io.write(data)
257
374
  end
@@ -259,6 +376,40 @@ describe Puppet::HTTP::Client do
259
376
 
260
377
  expect(io.string).to eq("abc")
261
378
  end
379
+
380
+ it 'raises an ArgumentError if `body` is missing' do
381
+ expect {
382
+ client.post(uri, nil, headers: {'Content-Type' => 'text/plain'})
383
+ }.to raise_error(ArgumentError, /'post' requires a string 'body' argument/)
384
+ end
385
+
386
+ it 'raises an ArgumentError if `content_type` is missing from the headers hash' do
387
+ expect {
388
+ client.post(uri, "")
389
+ }.to raise_error(ArgumentError, /'post' requires a 'content-type' header/)
390
+ end
391
+
392
+ context 'when connecting' do
393
+ it 'uses a specified ssl context' do
394
+ stub_request(:post, uri)
395
+
396
+ other_context = Puppet::SSL::SSLContext.new
397
+
398
+ client.post(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {body: "", ssl_context: other_context})
399
+ end
400
+
401
+ it 'uses the system store' do
402
+ stub_request(:post, uri)
403
+
404
+ client.post(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {include_system_store: true})
405
+ end
406
+
407
+ it 'raises an HTTPError if both are specified' do
408
+ expect {
409
+ client.post(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {ssl_context: puppet_context, include_system_store: true})
410
+ }.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
411
+ end
412
+ end
262
413
  end
263
414
 
264
415
  context "for DELETE requests" do
@@ -294,44 +445,80 @@ describe Puppet::HTTP::Client do
294
445
 
295
446
  expect(client.delete(uri).body).to eq("abc")
296
447
  end
448
+
449
+ context 'when connecting' do
450
+ it 'uses a specified ssl context' do
451
+ stub_request(:delete, uri)
452
+
453
+ other_context = Puppet::SSL::SSLContext.new
454
+
455
+ client.delete(uri, options: {ssl_context: other_context})
456
+ end
457
+
458
+ it 'uses the system store' do
459
+ stub_request(:delete, uri)
460
+
461
+ client.delete(uri, options: {include_system_store: true})
462
+ end
463
+
464
+ it 'raises an HTTPError if both are specified' do
465
+ expect {
466
+ client.delete(uri, options: {ssl_context: puppet_context, include_system_store: true})
467
+ }.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
468
+ end
469
+ end
297
470
  end
298
471
 
299
472
  context "Basic Auth" do
300
473
  it "submits credentials for GET requests" do
301
474
  stub_request(:get, uri).with(basic_auth: credentials)
302
475
 
303
- client.get(uri, user: 'user', password: 'pass')
476
+ client.get(uri, options: {basic_auth: {user: 'user', password: 'pass'}})
304
477
  end
305
478
 
306
479
  it "submits credentials for PUT requests" do
307
480
  stub_request(:put, uri).with(basic_auth: credentials)
308
481
 
309
- client.put(uri, content_type: 'text/plain', body: "hello", user: 'user', password: 'pass')
482
+ client.put(uri, "hello", headers: {'Content-Type' => 'text/plain'}, options: {basic_auth: {user: 'user', password: 'pass'}})
310
483
  end
311
484
 
312
485
  it "returns response containing access denied" do
313
486
  stub_request(:get, uri).with(basic_auth: credentials).to_return(status: [403, "Ye Shall Not Pass"])
314
487
 
315
- response = client.get(uri, user: 'user', password: 'pass')
488
+ response = client.get(uri, options: {basic_auth: {user: 'user', password: 'pass'}})
316
489
  expect(response.code).to eq(403)
317
490
  expect(response.reason).to eq("Ye Shall Not Pass")
318
491
  expect(response).to_not be_success
319
492
  end
320
493
 
321
- it 'omits basic auth if user is nil' do
494
+ it 'includes basic auth if user is nil' do
322
495
  stub_request(:get, uri).with do |req|
323
- expect(req.headers).to_not include('Authorization')
496
+ expect(req.headers).to include('Authorization')
324
497
  end
325
498
 
326
- client.get(uri, user: nil, password: 'pass')
499
+ client.get(uri, options: {basic_auth: {user: nil, password: 'pass'}})
327
500
  end
328
501
 
329
- it 'omits basic auth if password is nil' do
502
+ it 'includes basic auth if password is nil' do
330
503
  stub_request(:get, uri).with do |req|
331
- expect(req.headers).to_not include('Authorization')
504
+ expect(req.headers).to include('Authorization')
332
505
  end
333
506
 
334
- client.get(uri, user: 'user', password: nil)
507
+ client.get(uri, options: {basic_auth: {user: 'user', password: nil}})
508
+ end
509
+
510
+ it 'observes userinfo in the URL' do
511
+ stub_request(:get, uri).with(basic_auth: credentials)
512
+
513
+ client.get(URI("https://user:pass@www.example.com"))
514
+ end
515
+
516
+ it 'prefers explicit basic_auth credentials' do
517
+ uri = URI("https://ignored_user:ignored_pass@www.example.com")
518
+
519
+ stub_request(:get, "https://www.example.com").with(basic_auth: credentials)
520
+
521
+ client.get(uri, options: {basic_auth: {user: 'user', password: 'pass'}})
335
522
  end
336
523
  end
337
524
 
@@ -357,14 +544,45 @@ describe Puppet::HTTP::Client do
357
544
  stub_request(:put, start_url).to_return(redirect_to(url: bar_url))
358
545
  stub_request(:put, bar_url).to_return(status: 200)
359
546
 
360
- response = client.put(start_url, body: "", content_type: 'text/plain')
547
+ response = client.put(start_url, "", headers: {'Content-Type' => 'text/plain'})
548
+ expect(response).to be_success
549
+ end
550
+
551
+ it "updates the Host header from the Location host and port" do
552
+ stub_request(:get, start_url).with(headers: { 'Host' => 'www.example.com:8140' })
553
+ .to_return(redirect_to(url: other_host))
554
+ stub_request(:get, other_host).with(headers: { 'Host' => 'other.example.com:8140' })
555
+ .to_return(status: 200)
556
+
557
+ response = client.get(start_url)
558
+ expect(response).to be_success
559
+ end
560
+
561
+ it "omits the default HTTPS port from the Host header" do
562
+ stub_request(:get, start_url).with(headers: { 'Host' => 'www.example.com:8140' })
563
+ .to_return(redirect_to(url: "https://other.example.com/qux"))
564
+ stub_request(:get, "https://other.example.com/qux").with(headers: { 'Host' => 'other.example.com' })
565
+ .to_return(status: 200)
566
+
567
+ response = client.get(start_url)
568
+ expect(response).to be_success
569
+ end
570
+
571
+ it "omits the default HTTP port from the Host header" do
572
+ stub_request(:get, start_url).with(headers: { 'Host' => 'www.example.com:8140' })
573
+ .to_return(redirect_to(url: "http://other.example.com/qux"))
574
+ stub_request(:get, "http://other.example.com/qux").with(headers: { 'Host' => 'other.example.com' })
575
+ .to_return(status: 200)
576
+
577
+ response = client.get(start_url)
361
578
  expect(response).to be_success
362
579
  end
363
580
 
364
- it "preserves query parameters" do
365
- query = { 'debug' => true }
366
- stub_request(:get, start_url).with(query: query).to_return(redirect_to(url: bar_url))
367
- stub_request(:get, bar_url).with(query: query).to_return(status: 200)
581
+ it "applies query parameters from the location header" do
582
+ query = { 'redirected' => false }
583
+
584
+ stub_request(:get, start_url).with(query: query).to_return(redirect_to(url: "#{bar_url}?redirected=true"))
585
+ stub_request(:get, bar_url).with(query: {'redirected' => 'true'}).to_return(status: 200)
368
586
 
369
587
  response = client.get(start_url, params: query)
370
588
  expect(response).to be_success
@@ -383,7 +601,7 @@ describe Puppet::HTTP::Client do
383
601
  stub_request(:get, start_url).with(basic_auth: credentials).to_return(redirect_to(url: bar_url))
384
602
  stub_request(:get, bar_url).with(basic_auth: credentials).to_return(status: 200)
385
603
 
386
- client.get(start_url, user: 'user', password: 'pass')
604
+ client.get(start_url, options: {basic_auth: {user: 'user', password: 'pass'}})
387
605
  end
388
606
 
389
607
  it "redirects given a relative location" do
@@ -395,22 +613,33 @@ describe Puppet::HTTP::Client do
395
613
  expect(response).to be_success
396
614
  end
397
615
 
398
- it "preserves query parameters given a relative location" do
616
+ it "applies query parameters from the location header" do
399
617
  relative_url = "/people.html"
400
- query = { 'debug' => true }
401
- stub_request(:get, start_url).with(query: query).to_return(redirect_to(url: relative_url))
402
- stub_request(:get, "https://www.example.com:8140/people.html").with(query: query).to_return(status: 200)
618
+ query = { 'redirected' => false }
619
+ stub_request(:get, start_url).with(query: query).to_return(redirect_to(url: "#{relative_url}?redirected=true"))
620
+ stub_request(:get, "https://www.example.com:8140/people.html").with(query: {'redirected' => 'true'}).to_return(status: 200)
403
621
 
404
622
  response = client.get(start_url, params: query)
405
623
  expect(response).to be_success
406
624
  end
407
625
 
626
+ it "removes dot segments from a relative location" do
627
+ # from https://tools.ietf.org/html/rfc3986#section-5.4.2
628
+ base_url = URI("http://a/b/c/d;p?q")
629
+ relative_url = "../../../../g"
630
+ stub_request(:get, base_url).to_return(redirect_to(url: relative_url))
631
+ stub_request(:get, "http://a/g").to_return(status: 200)
632
+
633
+ response = client.get(base_url)
634
+ expect(response).to be_success
635
+ end
636
+
408
637
  it "preserves request body for each request" do
409
638
  data = 'some data'
410
639
  stub_request(:put, start_url).with(body: data).to_return(redirect_to(url: bar_url))
411
640
  stub_request(:put, bar_url).with(body: data).to_return(status: 200)
412
641
 
413
- response = client.put(start_url, body: data, content_type: 'text/plain')
642
+ response = client.put(start_url, data, headers: {'Content-Type' => 'text/plain'})
414
643
  expect(response).to be_success
415
644
  end
416
645
 
@@ -539,6 +768,32 @@ describe Puppet::HTTP::Client do
539
768
  }.to raise_error(Puppet::HTTP::ProtocolError, /Failed to parse Retry-After header 'foo' as an integer or RFC 2822 date/)
540
769
  end
541
770
 
771
+ it "should close the connection before sleeping" do
772
+ retry_after('42')
773
+
774
+ site = Puppet::Network::HTTP::Site.from_uri(uri)
775
+
776
+ http1 = Net::HTTP.new(site.host, site.port)
777
+ http1.use_ssl = true
778
+ allow(http1).to receive(:started?).and_return(true)
779
+
780
+ http2 = Net::HTTP.new(site.host, site.port)
781
+ http2.use_ssl = true
782
+ allow(http2).to receive(:started?).and_return(true)
783
+
784
+
785
+ pool = Puppet::Network::HTTP::Pool.new(15)
786
+ client = Puppet::HTTP::Client.new(pool: pool)
787
+
788
+ # The "with_connection" method is required to yield started connections
789
+ allow(pool).to receive(:with_connection).and_yield(http1).and_yield(http2)
790
+
791
+ expect(http1).to receive(:finish).ordered
792
+ expect(::Kernel).to receive(:sleep).with(42).ordered
793
+
794
+ client.get(uri)
795
+ end
796
+
542
797
  it "should sleep and retry if Retry-After is an Integer" do
543
798
  retry_after('42')
544
799
 
@@ -575,4 +830,34 @@ describe Puppet::HTTP::Client do
575
830
  client.get(uri)
576
831
  end
577
832
  end
833
+
834
+ context "persistent connections" do
835
+ before :each do
836
+ stub_request(:get, uri)
837
+ end
838
+
839
+ it 'defaults keepalive to http_keepalive_timeout' do
840
+ expect(client.pool.keepalive_timeout).to eq(Puppet[:http_keepalive_timeout])
841
+ end
842
+
843
+ it 'reuses a cached connection' do
844
+ allow(Puppet).to receive(:debug)
845
+ expect(Puppet).to receive(:debug).with(/^Creating new connection/)
846
+ expect(Puppet).to receive(:debug).with(/^Using cached connection/)
847
+
848
+ client.get(uri)
849
+ client.get(uri)
850
+ end
851
+
852
+ it 'can be disabled' do
853
+ Puppet[:http_keepalive_timeout] = 0
854
+
855
+ allow(Puppet).to receive(:debug)
856
+ expect(Puppet).to receive(:debug).with(/^Creating new connection/).twice
857
+ expect(Puppet).to receive(:debug).with(/^Using cached connection/).never
858
+
859
+ client.get(uri)
860
+ client.get(uri)
861
+ end
862
+ end
578
863
  end