puppet 6.11.1-x64-mingw32 → 6.16.0-x64-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 (395) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +3 -8
  3. data/CONTRIBUTING.md +7 -13
  4. data/Gemfile +1 -0
  5. data/Gemfile.lock +39 -36
  6. data/README.md +17 -24
  7. data/ext/build_defaults.yaml +1 -0
  8. data/ext/project_data.yaml +1 -1
  9. data/ext/windows/service/daemon.rb +25 -20
  10. data/lib/puppet.rb +52 -13
  11. data/lib/puppet/agent.rb +20 -14
  12. data/lib/puppet/application/agent.rb +12 -14
  13. data/lib/puppet/application/describe.rb +7 -5
  14. data/lib/puppet/application/device.rb +2 -2
  15. data/lib/puppet/application/filebucket.rb +19 -15
  16. data/lib/puppet/application/plugin.rb +1 -0
  17. data/lib/puppet/application/resource.rb +1 -1
  18. data/lib/puppet/application/ssl.rb +4 -4
  19. data/lib/puppet/concurrent.rb +2 -0
  20. data/lib/puppet/concurrent/lock.rb +16 -0
  21. data/lib/puppet/concurrent/synchronized.rb +15 -0
  22. data/lib/puppet/concurrent/thread_local_singleton.rb +14 -0
  23. data/lib/puppet/configurer.rb +85 -83
  24. data/lib/puppet/configurer/plugin_handler.rb +10 -1
  25. data/lib/puppet/context/trusted_information.rb +14 -8
  26. data/lib/puppet/daemon.rb +13 -27
  27. data/lib/puppet/defaults.rb +158 -40
  28. data/lib/puppet/environments.rb +30 -20
  29. data/lib/puppet/error.rb +9 -1
  30. data/lib/puppet/face/facts.rb +8 -5
  31. data/lib/puppet/face/help.rb +29 -3
  32. data/lib/puppet/face/module/search.rb +5 -0
  33. data/lib/puppet/face/plugin.rb +2 -2
  34. data/lib/puppet/file_serving/http_metadata.rb +1 -1
  35. data/lib/puppet/file_system/file_impl.rb +13 -9
  36. data/lib/puppet/file_system/memory_file.rb +6 -0
  37. data/lib/puppet/file_system/memory_impl.rb +13 -0
  38. data/lib/puppet/file_system/uniquefile.rb +4 -0
  39. data/lib/puppet/file_system/windows.rb +7 -10
  40. data/lib/puppet/forge.rb +3 -3
  41. data/lib/puppet/forge/errors.rb +2 -2
  42. data/lib/puppet/forge/repository.rb +31 -86
  43. data/lib/puppet/functions/call.rb +1 -1
  44. data/lib/puppet/functions/camelcase.rb +2 -2
  45. data/lib/puppet/functions/epp.rb +4 -4
  46. data/lib/puppet/functions/eyaml_lookup_key.rb +13 -8
  47. data/lib/puppet/functions/filter.rb +1 -0
  48. data/lib/puppet/functions/find_file.rb +9 -9
  49. data/lib/puppet/functions/find_template.rb +63 -0
  50. data/lib/puppet/functions/inline_epp.rb +5 -5
  51. data/lib/puppet/functions/reduce.rb +2 -4
  52. data/lib/puppet/http.rb +7 -0
  53. data/lib/puppet/http/client.rb +341 -54
  54. data/lib/puppet/http/errors.rb +2 -0
  55. data/lib/puppet/http/external_client.rb +90 -0
  56. data/lib/puppet/http/redirector.rb +34 -0
  57. data/lib/puppet/http/resolver.rb +57 -1
  58. data/lib/puppet/http/resolver/server_list.rb +98 -0
  59. data/lib/puppet/http/resolver/settings.rb +23 -2
  60. data/lib/puppet/http/resolver/srv.rb +36 -4
  61. data/lib/puppet/http/response.rb +68 -1
  62. data/lib/puppet/http/retry_after_handler.rb +39 -0
  63. data/lib/puppet/http/service.rb +179 -3
  64. data/lib/puppet/http/service/ca.rb +84 -21
  65. data/lib/puppet/http/service/compiler.rb +319 -0
  66. data/lib/puppet/http/service/file_server.rb +206 -0
  67. data/lib/puppet/http/service/report.rb +66 -0
  68. data/lib/puppet/http/session.rb +106 -31
  69. data/lib/puppet/indirector/catalog/compiler.rb +10 -0
  70. data/lib/puppet/indirector/catalog/rest.rb +34 -0
  71. data/lib/puppet/indirector/facts/rest.rb +42 -0
  72. data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
  73. data/lib/puppet/indirector/file_bucket_file/rest.rb +48 -0
  74. data/lib/puppet/indirector/file_content/http.rb +5 -0
  75. data/lib/puppet/indirector/file_content/rest.rb +30 -0
  76. data/lib/puppet/indirector/file_metadata/http.rb +4 -4
  77. data/lib/puppet/indirector/file_metadata/rest.rb +52 -0
  78. data/lib/puppet/indirector/json.rb +1 -1
  79. data/lib/puppet/indirector/msgpack.rb +1 -1
  80. data/lib/puppet/indirector/node/rest.rb +24 -0
  81. data/lib/puppet/indirector/report/rest.rb +19 -0
  82. data/lib/puppet/indirector/report/yaml.rb +23 -0
  83. data/lib/puppet/indirector/rest.rb +12 -0
  84. data/lib/puppet/indirector/status/rest.rb +18 -0
  85. data/lib/puppet/loaders.rb +6 -0
  86. data/lib/puppet/metatype/manager.rb +80 -80
  87. data/lib/puppet/network/http/base_pool.rb +19 -1
  88. data/lib/puppet/network/http/compression.rb +7 -0
  89. data/lib/puppet/network/http/connection.rb +6 -0
  90. data/lib/puppet/network/http/connection_adapter.rb +182 -0
  91. data/lib/puppet/network/http/nocache_pool.rb +2 -0
  92. data/lib/puppet/network/http/pool.rb +13 -6
  93. data/lib/puppet/network/http_pool.rb +2 -1
  94. data/lib/puppet/node/environment.rb +24 -8
  95. data/lib/puppet/pal/catalog_compiler.rb +5 -0
  96. data/lib/puppet/pal/pal_impl.rb +9 -29
  97. data/lib/puppet/parser/ast/pops_bridge.rb +6 -11
  98. data/lib/puppet/parser/compiler.rb +42 -32
  99. data/lib/puppet/parser/functions.rb +18 -13
  100. data/lib/puppet/parser/functions/epp.rb +3 -3
  101. data/lib/puppet/parser/functions/filter.rb +1 -0
  102. data/lib/puppet/parser/functions/inline_epp.rb +5 -5
  103. data/lib/puppet/pops/evaluator/access_operator.rb +2 -2
  104. data/lib/puppet/pops/evaluator/evaluator_impl.rb +1 -1
  105. data/lib/puppet/pops/evaluator/runtime3_support.rb +1 -1
  106. data/lib/puppet/pops/loader/puppet_plan_instantiator.rb +12 -3
  107. data/lib/puppet/pops/loaders.rb +7 -5
  108. data/lib/puppet/pops/lookup/invocation.rb +10 -3
  109. data/lib/puppet/pops/model/pn_transformer.rb +5 -9
  110. data/lib/puppet/pops/parser/evaluating_parser.rb +8 -11
  111. data/lib/puppet/pops/serialization/json_path.rb +3 -3
  112. data/lib/puppet/pops/time/timespan.rb +3 -5
  113. data/lib/puppet/pops/types/p_object_type_extension.rb +10 -0
  114. data/lib/puppet/pops/types/string_converter.rb +6 -9
  115. data/lib/puppet/pops/types/type_calculator.rb +30 -10
  116. data/lib/puppet/pops/types/type_formatter.rb +9 -11
  117. data/lib/puppet/pops/types/type_parser.rb +3 -3
  118. data/lib/puppet/pops/validation/checker4_0.rb +1 -1
  119. data/lib/puppet/pops/validation/tasks_checker.rb +5 -1
  120. data/lib/puppet/provider/aix_object.rb +4 -2
  121. data/lib/puppet/provider/group/aix.rb +1 -0
  122. data/lib/puppet/provider/group/groupadd.rb +57 -24
  123. data/lib/puppet/provider/group/windows_adsi.rb +3 -3
  124. data/lib/puppet/provider/package/aix.rb +17 -2
  125. data/lib/puppet/provider/package/apt.rb +78 -4
  126. data/lib/puppet/provider/package/dnfmodule.rb +69 -15
  127. data/lib/puppet/provider/package/dpkg.rb +14 -7
  128. data/lib/puppet/provider/package/fink.rb +20 -3
  129. data/lib/puppet/provider/package/gem.rb +41 -7
  130. data/lib/puppet/provider/package/openbsd.rb +13 -1
  131. data/lib/puppet/provider/package/pacman.rb +2 -5
  132. data/lib/puppet/provider/package/pip.rb +143 -48
  133. data/lib/puppet/provider/package/pip3.rb +0 -2
  134. data/lib/puppet/provider/package/pkg.rb +18 -5
  135. data/lib/puppet/provider/package/pkgdmg.rb +1 -1
  136. data/lib/puppet/provider/package/pkgng.rb +16 -4
  137. data/lib/puppet/provider/package/portage.rb +5 -5
  138. data/lib/puppet/provider/package/puppet_gem.rb +6 -2
  139. data/lib/puppet/provider/package/rpm.rb +6 -213
  140. data/lib/puppet/provider/package/yum.rb +108 -24
  141. data/lib/puppet/provider/package/zypper.rb +59 -1
  142. data/lib/puppet/provider/package_targetable.rb +5 -4
  143. data/lib/puppet/provider/service/systemd.rb +23 -5
  144. data/lib/puppet/provider/user/aix.rb +1 -0
  145. data/lib/puppet/provider/user/directoryservice.rb +30 -5
  146. data/lib/puppet/provider/user/hpux.rb +1 -1
  147. data/lib/puppet/provider/user/useradd.rb +11 -8
  148. data/lib/puppet/reports/http.rb +13 -9
  149. data/lib/puppet/reports/store.rb +1 -1
  150. data/lib/puppet/resource/type_collection.rb +20 -16
  151. data/lib/puppet/runtime.rb +32 -1
  152. data/lib/puppet/settings.rb +4 -0
  153. data/lib/puppet/settings/http_extra_headers_setting.rb +25 -0
  154. data/lib/puppet/ssl.rb +1 -0
  155. data/lib/puppet/ssl/certificate.rb +2 -1
  156. data/lib/puppet/ssl/host.rb +4 -4
  157. data/lib/puppet/ssl/oids.rb +1 -0
  158. data/lib/puppet/ssl/ssl_provider.rb +20 -0
  159. data/lib/puppet/ssl/state_machine.rb +81 -35
  160. data/lib/puppet/ssl/verifier_adapter.rb +9 -1
  161. data/lib/puppet/test/test_helper.rb +7 -1
  162. data/lib/puppet/transaction.rb +33 -11
  163. data/lib/puppet/transaction/report.rb +2 -2
  164. data/lib/puppet/transaction/resource_harness.rb +1 -1
  165. data/lib/puppet/type.rb +7 -2
  166. data/lib/puppet/type/file.rb +13 -0
  167. data/lib/puppet/type/file/data_sync.rb +5 -1
  168. data/lib/puppet/type/file/source.rb +49 -58
  169. data/lib/puppet/type/group.rb +5 -4
  170. data/lib/puppet/type/package.rb +102 -10
  171. data/lib/puppet/type/service.rb +6 -8
  172. data/lib/puppet/type/user.rb +6 -30
  173. data/lib/puppet/util.rb +34 -11
  174. data/lib/puppet/util/at_fork.rb +1 -1
  175. data/lib/puppet/util/autoload.rb +4 -18
  176. data/lib/puppet/util/instance_loader.rb +14 -10
  177. data/lib/puppet/util/log/destinations.rb +2 -11
  178. data/lib/puppet/util/logging.rb +30 -18
  179. data/lib/puppet/util/package/version/debian.rb +175 -0
  180. data/lib/puppet/util/package/version/gem.rb +15 -0
  181. data/lib/puppet/util/package/version/pip.rb +167 -0
  182. data/lib/puppet/util/package/version/range.rb +53 -0
  183. data/lib/puppet/util/package/version/range/eq.rb +14 -0
  184. data/lib/puppet/util/package/version/range/gt.rb +14 -0
  185. data/lib/puppet/util/package/version/range/gt_eq.rb +14 -0
  186. data/lib/puppet/util/package/version/range/lt.rb +14 -0
  187. data/lib/puppet/util/package/version/range/lt_eq.rb +14 -0
  188. data/lib/puppet/util/package/version/range/min_max.rb +21 -0
  189. data/lib/puppet/util/package/version/range/simple.rb +11 -0
  190. data/lib/puppet/util/package/version/rpm.rb +73 -0
  191. data/lib/puppet/util/pidlock.rb +36 -10
  192. data/lib/puppet/util/platform.rb +5 -0
  193. data/lib/puppet/util/plist.rb +6 -0
  194. data/lib/puppet/util/rpm_compare.rb +193 -0
  195. data/lib/puppet/util/storage.rb +0 -1
  196. data/lib/puppet/util/windows/adsi.rb +50 -20
  197. data/lib/puppet/util/windows/process.rb +15 -14
  198. data/lib/puppet/util/windows/security.rb +1 -0
  199. data/lib/puppet/util/windows/sid.rb +3 -3
  200. data/lib/puppet/util/yaml.rb +1 -1
  201. data/lib/puppet/version.rb +1 -1
  202. data/lib/puppet/x509/cert_provider.rb +9 -5
  203. data/locales/puppet.pot +640 -521
  204. data/man/man5/puppet.conf.5 +88 -9
  205. data/man/man8/puppet-agent.8 +6 -6
  206. data/man/man8/puppet-apply.8 +1 -1
  207. data/man/man8/puppet-catalog.8 +1 -1
  208. data/man/man8/puppet-config.8 +1 -1
  209. data/man/man8/puppet-describe.8 +1 -1
  210. data/man/man8/puppet-device.8 +2 -2
  211. data/man/man8/puppet-doc.8 +1 -1
  212. data/man/man8/puppet-epp.8 +1 -1
  213. data/man/man8/puppet-facts.8 +1 -1
  214. data/man/man8/puppet-filebucket.8 +17 -2
  215. data/man/man8/puppet-generate.8 +1 -1
  216. data/man/man8/puppet-help.8 +6 -3
  217. data/man/man8/puppet-key.8 +1 -1
  218. data/man/man8/puppet-lookup.8 +1 -1
  219. data/man/man8/puppet-man.8 +1 -1
  220. data/man/man8/puppet-module.8 +4 -1
  221. data/man/man8/puppet-node.8 +1 -1
  222. data/man/man8/puppet-parser.8 +1 -1
  223. data/man/man8/puppet-plugin.8 +1 -1
  224. data/man/man8/puppet-report.8 +1 -1
  225. data/man/man8/puppet-resource.8 +1 -1
  226. data/man/man8/puppet-script.8 +1 -1
  227. data/man/man8/puppet-ssl.8 +2 -2
  228. data/man/man8/puppet-status.8 +1 -1
  229. data/man/man8/puppet.8 +2 -2
  230. data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +67 -0
  231. data/spec/fixtures/ssl/unknown-127.0.0.1.pem +48 -0
  232. data/spec/fixtures/ssl/unknown-ca-key.pem +67 -0
  233. data/spec/fixtures/ssl/unknown-ca.pem +59 -0
  234. data/spec/fixtures/unit/forge/bacula.json +76 -0
  235. data/spec/fixtures/unit/provider/package/dnfmodule/{dnf-module-list-installed.txt → dnf-module-list.txt} +8 -0
  236. data/spec/fixtures/unit/provider/package/pkgng/pkg.version +2 -0
  237. data/spec/fixtures/unit/provider/package/yum/yum-check-update-subscription-manager.txt +9 -0
  238. data/spec/fixtures/unit/provider/package/zypper/zypper-search-uninstalled.out +13 -0
  239. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services +9 -0
  240. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_fetch_if_not_on_the_local_disk.yml +1 -102
  241. 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 -106
  242. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_update_if_content_differs_on_disk.yml +1 -106
  243. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_mtime_is_older_on_disk.yml +1 -102
  244. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_no_header_specified.yml +1 -98
  245. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_not_on_the_local_disk.yml +1 -102
  246. 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 -102
  247. data/spec/integration/application/agent_spec.rb +394 -0
  248. data/spec/integration/application/apply_spec.rb +132 -3
  249. data/spec/integration/application/filebucket_spec.rb +190 -0
  250. data/spec/integration/application/plugin_spec.rb +73 -0
  251. data/spec/integration/configurer_spec.rb +26 -7
  252. data/spec/integration/http/client_spec.rb +154 -0
  253. data/spec/integration/indirector/facts/facter_spec.rb +4 -0
  254. data/spec/integration/indirector/report/yaml.rb +83 -0
  255. data/spec/integration/module_tool/forge_spec.rb +51 -0
  256. data/spec/integration/network/http_pool_spec.rb +76 -20
  257. data/spec/integration/node/environment_spec.rb +15 -0
  258. data/spec/integration/util/windows/adsi_spec.rb +6 -1
  259. data/spec/lib/puppet/test_ca.rb +2 -2
  260. data/spec/lib/puppet_spec/https.rb +20 -9
  261. data/spec/lib/puppet_spec/puppetserver.rb +119 -0
  262. data/spec/shared_contexts/https.rb +29 -0
  263. data/spec/spec_helper.rb +6 -2
  264. data/spec/unit/agent_spec.rb +80 -26
  265. data/spec/unit/application/agent_spec.rb +9 -5
  266. data/spec/unit/application/apply_spec.rb +2 -12
  267. data/spec/unit/application/describe_spec.rb +88 -50
  268. data/spec/unit/application/device_spec.rb +2 -2
  269. data/spec/unit/application/filebucket_spec.rb +22 -2
  270. data/spec/unit/application/resource_spec.rb +2 -2
  271. data/spec/unit/concurrent/lock_spec.rb +29 -0
  272. data/spec/unit/configurer/fact_handler_spec.rb +0 -4
  273. data/spec/unit/configurer/plugin_handler_spec.rb +36 -19
  274. data/spec/unit/configurer_spec.rb +400 -406
  275. data/spec/unit/context/trusted_information_spec.rb +17 -0
  276. data/spec/unit/daemon_spec.rb +5 -64
  277. data/spec/unit/defaults_spec.rb +38 -4
  278. data/spec/unit/environments_spec.rb +65 -28
  279. data/spec/unit/face/facts_spec.rb +24 -20
  280. data/spec/unit/face/module/search_spec.rb +17 -0
  281. data/spec/unit/face/plugin_spec.rb +12 -10
  282. data/spec/unit/file_system/uniquefile_spec.rb +11 -0
  283. data/spec/unit/file_system_spec.rb +26 -2
  284. data/spec/unit/forge/errors_spec.rb +1 -1
  285. data/spec/unit/forge/forge_spec.rb +12 -54
  286. data/spec/unit/forge/module_release_spec.rb +19 -6
  287. data/spec/unit/forge/repository_spec.rb +63 -157
  288. data/spec/unit/forge_spec.rb +46 -116
  289. data/spec/unit/functions/find_template_spec.rb +69 -0
  290. data/spec/unit/functions/lookup_spec.rb +13 -0
  291. data/spec/unit/http/client_spec.rb +395 -27
  292. data/spec/unit/http/external_client_spec.rb +201 -0
  293. data/spec/unit/http/resolver_spec.rb +81 -12
  294. data/spec/unit/http/response_spec.rb +69 -0
  295. data/spec/unit/http/service/ca_spec.rb +100 -7
  296. data/spec/unit/http/service/compiler_spec.rb +627 -0
  297. data/spec/unit/http/service/file_server_spec.rb +308 -0
  298. data/spec/unit/http/service/report_spec.rb +118 -0
  299. data/spec/unit/http/service_spec.rb +117 -4
  300. data/spec/unit/http/session_spec.rb +237 -19
  301. data/spec/unit/indirector/catalog/compiler_spec.rb +47 -29
  302. data/spec/unit/indirector/catalog/rest_spec.rb +59 -2
  303. data/spec/unit/indirector/facts/rest_spec.rb +79 -24
  304. data/spec/unit/indirector/file_bucket_file/rest_spec.rb +82 -2
  305. data/spec/unit/indirector/file_content/rest_spec.rb +53 -2
  306. data/spec/unit/indirector/file_metadata/http_spec.rb +167 -0
  307. data/spec/unit/indirector/file_metadata/rest_spec.rb +110 -2
  308. data/spec/unit/indirector/node/rest_spec.rb +57 -2
  309. data/spec/unit/indirector/report/rest_spec.rb +58 -51
  310. data/spec/unit/indirector/resource/ral_spec.rb +7 -8
  311. data/spec/unit/indirector/rest_spec.rb +13 -0
  312. data/spec/unit/indirector/status/rest_spec.rb +43 -2
  313. data/spec/unit/network/http/connection_spec.rb +549 -176
  314. data/spec/unit/network/http/nocache_pool_spec.rb +25 -3
  315. data/spec/unit/network/http/pool_spec.rb +89 -11
  316. data/spec/unit/network/http_pool_spec.rb +63 -57
  317. data/spec/unit/network/http_spec.rb +1 -1
  318. data/spec/unit/node/environment_spec.rb +16 -0
  319. data/spec/unit/node/facts_spec.rb +2 -1
  320. data/spec/unit/node_spec.rb +7 -4
  321. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +8 -3
  322. data/spec/unit/pops/serialization/to_from_hr_spec.rb +6 -1
  323. data/spec/unit/pops/validator/validator_spec.rb +7 -2
  324. data/spec/unit/provider/aix_object_spec.rb +16 -2
  325. data/spec/unit/provider/group/groupadd_spec.rb +181 -56
  326. data/spec/unit/provider/group/windows_adsi_spec.rb +43 -10
  327. data/spec/unit/provider/package/aix_spec.rb +29 -0
  328. data/spec/unit/provider/package/apt_spec.rb +43 -2
  329. data/spec/unit/provider/package/aptitude_spec.rb +1 -0
  330. data/spec/unit/provider/package/dnfmodule_spec.rb +76 -15
  331. data/spec/unit/provider/package/dpkg_spec.rb +28 -6
  332. data/spec/unit/provider/package/gem_spec.rb +40 -0
  333. data/spec/unit/provider/package/openbsd_spec.rb +17 -0
  334. data/spec/unit/provider/package/pacman_spec.rb +6 -21
  335. data/spec/unit/provider/package/pip_spec.rb +68 -19
  336. data/spec/unit/provider/package/pkg_spec.rb +15 -1
  337. data/spec/unit/provider/package/pkgdmg_spec.rb +1 -1
  338. data/spec/unit/provider/package/pkgng_spec.rb +38 -0
  339. data/spec/unit/provider/package/portage_spec.rb +9 -4
  340. data/spec/unit/provider/package/puppet_gem_spec.rb +8 -0
  341. data/spec/unit/provider/package/rpm_spec.rb +0 -212
  342. data/spec/unit/provider/package/yum_spec.rb +292 -0
  343. data/spec/unit/provider/package/zypper_spec.rb +84 -0
  344. data/spec/unit/provider/package_targetable_spec.rb +60 -0
  345. data/spec/unit/provider/service/init_spec.rb +1 -0
  346. data/spec/unit/provider/service/openbsd_spec.rb +9 -0
  347. data/spec/unit/provider/service/openwrt_spec.rb +1 -0
  348. data/spec/unit/provider/service/redhat_spec.rb +9 -0
  349. data/spec/unit/provider/service/systemd_spec.rb +92 -12
  350. data/spec/unit/provider/user/directoryservice_spec.rb +41 -0
  351. data/spec/unit/provider/user/hpux_spec.rb +2 -2
  352. data/spec/unit/provider/user/useradd_spec.rb +21 -8
  353. data/spec/unit/provider/user/windows_adsi_spec.rb +3 -3
  354. data/spec/unit/puppet_pal_2pec.rb +0 -26
  355. data/spec/unit/puppet_pal_catalog_spec.rb +46 -0
  356. data/spec/unit/puppet_spec.rb +47 -0
  357. data/spec/unit/reports/http_spec.rb +70 -52
  358. data/spec/unit/settings/autosign_setting_spec.rb +1 -1
  359. data/spec/unit/settings/http_extra_headers_spec.rb +64 -0
  360. data/spec/unit/ssl/certificate_spec.rb +7 -0
  361. data/spec/unit/ssl/host_spec.rb +4 -2
  362. data/spec/unit/ssl/oids_spec.rb +1 -0
  363. data/spec/unit/ssl/ssl_provider_spec.rb +71 -0
  364. data/spec/unit/ssl/state_machine_spec.rb +99 -13
  365. data/spec/unit/transaction/persistence_spec.rb +1 -10
  366. data/spec/unit/transaction/report_spec.rb +4 -0
  367. data/spec/unit/transaction_spec.rb +45 -1
  368. data/spec/unit/type/file/content_spec.rb +9 -3
  369. data/spec/unit/type/file/ensure_spec.rb +1 -2
  370. data/spec/unit/type/file/source_spec.rb +86 -35
  371. data/spec/unit/type/package_spec.rb +8 -0
  372. data/spec/unit/type/service_spec.rb +9 -8
  373. data/spec/unit/type/user_spec.rb +1 -2
  374. data/spec/unit/util/at_fork_spec.rb +3 -2
  375. data/spec/unit/util/autoload_spec.rb +2 -1
  376. data/spec/unit/util/log/destinations_spec.rb +1 -29
  377. data/spec/unit/util/log_spec.rb +0 -138
  378. data/spec/unit/util/logging_spec.rb +200 -0
  379. data/spec/unit/util/package/version/debian_spec.rb +83 -0
  380. data/spec/unit/util/package/version/pip_spec.rb +464 -0
  381. data/spec/unit/util/package/version/range_spec.rb +175 -0
  382. data/spec/unit/util/package/version/rpm_spec.rb +121 -0
  383. data/spec/unit/util/pidlock_spec.rb +112 -42
  384. data/spec/unit/util/plist_spec.rb +20 -0
  385. data/spec/unit/util/rpm_compare_spec.rb +196 -0
  386. data/spec/unit/util/storage_spec.rb +1 -8
  387. data/spec/unit/util/windows/adsi_spec.rb +55 -4
  388. data/spec/unit/util/windows/sid_spec.rb +2 -2
  389. data/spec/unit/x509/cert_provider_spec.rb +24 -4
  390. data/tasks/generate_cert_fixtures.rake +15 -1
  391. data/tasks/manpages.rake +6 -35
  392. metadata +92 -12
  393. data/COMMITTERS.md +0 -244
  394. data/spec/integration/faces/plugin_spec.rb +0 -61
  395. data/spec/lib/puppet_spec/validators.rb +0 -37
@@ -51,7 +51,7 @@
51
51
  #
52
52
  # Would notice the value of `$facts['processors']['count']` at the time when the `call` is made.
53
53
  #
54
- # * Deferred values supported since Puppet 5.6.0
54
+ # * Deferred values supported since Puppet 6.0
55
55
  #
56
56
  # @since 5.0.0
57
57
  #
@@ -23,8 +23,8 @@
23
23
  #
24
24
  # @example Camelcase of strings in an Array
25
25
  # ```puppet
26
- # ['abc_def', 'bcd_xyz'].capitalize()
27
- # capitalize(['abc_def', 'bcd_xyz'])
26
+ # ['abc_def', 'bcd_xyz'].camelcase()
27
+ # camelcase(['abc_def', 'bcd_xyz'])
28
28
  # ```
29
29
  # Would both result in `['AbcDef', 'BcdXyz']`
30
30
  #
@@ -6,12 +6,12 @@
6
6
  # The first argument to this function should be a `<MODULE NAME>/<TEMPLATE FILE>`
7
7
  # reference, which loads `<TEMPLATE FILE>` from `<MODULE NAME>`'s `templates`
8
8
  # directory. In most cases, the last argument is optional; if used, it should be a
9
- # [hash](/puppet/latest/reference/lang_data_hash.html) that contains parameters to
9
+ # [hash](https://puppet.com/docs/puppet/latest/lang_data_hash.html) that contains parameters to
10
10
  # pass to the template.
11
11
  #
12
- # - See the [template](/puppet/latest/reference/lang_template.html) documentation
13
- # for general template usage information.
14
- # - See the [EPP syntax](/puppet/latest/reference/lang_template_epp.html)
12
+ # - See the [template](https://puppet.com/docs/puppet/latest/lang_template.html)
13
+ # documentation for general template usage information.
14
+ # - See the [EPP syntax](https://puppet.com/docs/puppet/latest/lang_template_epp.html)
15
15
  # documentation for examples of EPP.
16
16
  #
17
17
  # For example, to call the apache module's `templates/vhost/_docroot.epp`
@@ -39,7 +39,7 @@ Puppet::Functions.create_function(:eyaml_lookup_key) do
39
39
  context.cache(nil, raw_data)
40
40
  end
41
41
  context.not_found unless raw_data.include?(key)
42
- context.cache(key, decrypt_value(raw_data[key], context, options))
42
+ context.cache(key, decrypt_value(raw_data[key], context, options, key))
43
43
  end
44
44
 
45
45
  def load_data_hash(options, context)
@@ -62,22 +62,22 @@ Puppet::Functions.create_function(:eyaml_lookup_key) do
62
62
  end
63
63
  end
64
64
 
65
- def decrypt_value(value, context, options)
65
+ def decrypt_value(value, context, options, key)
66
66
  case value
67
67
  when String
68
- decrypt(value, context, options)
68
+ decrypt(value, context, options, key)
69
69
  when Hash
70
70
  result = {}
71
- value.each_pair { |k, v| result[context.interpolate(k)] = decrypt_value(v, context, options) }
71
+ value.each_pair { |k, v| result[context.interpolate(k)] = decrypt_value(v, context, options, key) }
72
72
  result
73
73
  when Array
74
- value.map { |v| decrypt_value(v, context, options) }
74
+ value.map { |v| decrypt_value(v, context, options, key) }
75
75
  else
76
76
  value
77
77
  end
78
78
  end
79
79
 
80
- def decrypt(data, context, options)
80
+ def decrypt(data, context, options, key)
81
81
  if encrypted?(data)
82
82
  # Options must be set prior to each call to #parse since they end up as static variables in
83
83
  # the Options class. They cannot be set once before #decrypt_value is called, since each #decrypt
@@ -85,8 +85,13 @@ Puppet::Functions.create_function(:eyaml_lookup_key) do
85
85
  # config.
86
86
  #
87
87
  Hiera::Backend::Eyaml::Options.set(options)
88
- tokens = Hiera::Backend::Eyaml::Parser::ParserFactory.hiera_backend_parser.parse(data)
89
- data = tokens.map(&:to_plain_text).join.chomp
88
+ begin
89
+ tokens = Hiera::Backend::Eyaml::Parser::ParserFactory.hiera_backend_parser.parse(data)
90
+ data = tokens.map(&:to_plain_text).join.chomp
91
+ rescue StandardError => ex
92
+ raise Puppet::DataBinding::LookupError,
93
+ _("hiera-eyaml backend error decrypting %{data} when looking up %{key} in %{path}. Error was %{message}") % { data: data, key: key, path: options['path'], message: ex.message }
94
+ end
90
95
  end
91
96
  context.interpolate(data)
92
97
  end
@@ -38,6 +38,7 @@
38
38
  # $data = { "orange" => 0, "blueberry" => 1, "raspberry" => 2 }
39
39
  # $filtered_data = $data.filter |$items| { $items[0] =~ /berry$/ }
40
40
  # # $filtered_data = {blueberry => 1, raspberry => 2}
41
+ # ```
41
42
  #
42
43
  # When the first argument is an array and the lambda has two parameters, Puppet passes the
43
44
  # array's indexes (enumerated from 0) in the first parameter and its values in the second
@@ -1,19 +1,19 @@
1
1
  # Finds an existing file from a module and returns its path.
2
2
  #
3
- # The argument to this function should be a String as a `<MODULE NAME>/<FILE>`
4
- # reference, which will search for `<FILE>` relative to a module's `files`
3
+ # This function accepts an argument that is a String as a `<MODULE NAME>/<FILE>`
4
+ # reference, which searches for `<FILE>` relative to a module's `files`
5
5
  # directory. (For example, the reference `mysql/mysqltuner.pl` will search for the
6
6
  # file `<MODULES DIRECTORY>/mysql/files/mysqltuner.pl`.)
7
7
  #
8
8
  # This function can also accept:
9
- #
10
- # * An absolute String path, which will check for the existence of a file from anywhere on disk.
11
- # * Multiple String arguments, which will return the path of the **first** file
12
- # found, skipping non existing files.
13
- # * An array of string paths, which will return the path of the **first** file
14
- # found from the given paths in the array, skipping non existing files.
15
9
  #
16
- # The function returns `undef` if none of the given paths were found
10
+ # * An absolute String path, which checks for the existence of a file from anywhere on disk.
11
+ # * Multiple String arguments, which returns the path of the **first** file
12
+ # found, skipping nonexistent files.
13
+ # * An array of string paths, which returns the path of the **first** file
14
+ # found from the given paths in the array, skipping nonexistent files.
15
+ #
16
+ # The function returns `undef` if none of the given paths were found.
17
17
  #
18
18
  # @since 4.8.0
19
19
  #
@@ -0,0 +1,63 @@
1
+ # Finds an existing template from a module and returns its path.
2
+ #
3
+ # This function accepts an argument that is a String as a `<MODULE NAME>/<TEMPLATE>`
4
+ # reference, which searches for `<TEMPLATE>` relative to a module's `templates`
5
+ # directory on the master. (For example, the reference `mymod/secret.conf.epp`
6
+ # will search for the file `<MODULES DIRECTORY>/mymod/templates/secret.conf.epp`.)
7
+ #
8
+ # The primary use case is for agent-side template rendering with late-bound variables
9
+ # resolved, such as from secret stores inaccessible to the master, such as
10
+ #
11
+ # ```
12
+ # $variables = {
13
+ # 'password' => Deferred('vault_lookup::lookup',
14
+ # ['secret/mymod', 'https://vault.example.com:8200']),
15
+ # }
16
+ #
17
+ # # compile the template source into the catalog
18
+ # file { '/etc/secrets.conf':
19
+ # ensure => file,
20
+ # content => Deferred('inline_epp',
21
+ # [find_template('mymod/secret.conf.epp').file, $variables]),
22
+ # }
23
+ # ```
24
+ #
25
+ #
26
+ #
27
+ # This function can also accept:
28
+ #
29
+ # * An absolute String path, which checks for the existence of a template from anywhere on disk.
30
+ # * Multiple String arguments, which returns the path of the **first** template
31
+ # found, skipping nonexistent files.
32
+ # * An array of string paths, which returns the path of the **first** template
33
+ # found from the given paths in the array, skipping nonexistent files.
34
+ #
35
+ # The function returns `undef` if none of the given paths were found.
36
+ #
37
+ # @since 6.x
38
+ #
39
+ Puppet::Functions.create_function(:find_template, Puppet::Functions::InternalFunction) do
40
+ dispatch :find_template do
41
+ scope_param
42
+ repeated_param 'String', :paths
43
+ end
44
+
45
+ dispatch :find_template_array do
46
+ scope_param
47
+ repeated_param 'Array[String]', :paths_array
48
+ end
49
+
50
+ def find_template_array(scope, array)
51
+ find_template(scope, *array)
52
+ end
53
+
54
+ def find_template(scope, *args)
55
+ args.each do |file|
56
+ found = Puppet::Parser::Files.find_template(file, scope.compiler.environment)
57
+ if found && Puppet::FileSystem.exist?(found)
58
+ return found
59
+ end
60
+ end
61
+ nil
62
+ end
63
+ end
@@ -5,12 +5,12 @@
5
5
  #
6
6
  # The first argument to this function should be a string containing an EPP
7
7
  # template. In most cases, the last argument is optional; if used, it should be a
8
- # [hash](/puppet/latest/reference/lang_data_hash.html) that contains parameters to
8
+ # [hash](https://puppet.com/docs/puppet/latest/lang_data_hash.html) that contains parameters to
9
9
  # pass to the template.
10
10
  #
11
- # - See the [template](/puppet/latest/reference/lang_template.html) documentation
12
- # for general template usage information.
13
- # - See the [EPP syntax](/puppet/latest/reference/lang_template_epp.html)
11
+ # - See the [template](https://puppet.com/docs/puppet/latest/lang_template.html)
12
+ # documentation for general template usage information.
13
+ # - See the [EPP syntax](https://puppet.com/docs/puppet/latest/lang_template_epp.html)
14
14
  # documentation for examples of EPP.
15
15
  #
16
16
  # For example, to evaluate an inline EPP template and pass it the `docroot` and
@@ -28,7 +28,7 @@
28
28
  # `inline_epp` function fails to pass any required parameter.
29
29
  #
30
30
  # An inline EPP template should be written as a single-quoted string or
31
- # [heredoc](/puppet/latest/reference/lang_data_string.html#heredocs).
31
+ # [heredoc](https://puppet.com/docs/puppet/latest/lang_data_string.html#heredocs).
32
32
  # A double-quoted string is subject to expression interpolation before the string
33
33
  # is parsed as an EPP template.
34
34
  #
@@ -39,11 +39,9 @@
39
39
  # values to the lambda.
40
40
  #
41
41
  # Puppet calls the lambda for each of the data structure's remaining values. For each
42
- # call, it passes the result of the previous call as the first parameter ($memo in the
42
+ # call, it passes the result of the previous call as the first parameter (`$memo` in the
43
43
  # above examples) and the next value from the data structure as the second parameter
44
- # ($value).
45
- #
46
- # If the structure has one value, Puppet returns the value and does not call the lambda.
44
+ # (`$value`).
47
45
  #
48
46
  # @example Using the `reduce` function
49
47
  #
@@ -11,19 +11,26 @@ module Puppet
11
11
  end
12
12
  end
13
13
 
14
+ # @api private
14
15
  module HTTP
15
16
  ACCEPT_ENCODING = "gzip;q=1.0,deflate;q=0.6,identity;q=0.3".freeze
17
+ HEADER_PUPPET_VERSION = "X-Puppet-Version".freeze
16
18
 
17
19
  require 'puppet/http/errors'
18
20
  require 'puppet/http/response'
19
21
  require 'puppet/http/service'
20
22
  require 'puppet/http/service/ca'
23
+ require 'puppet/http/service/compiler'
24
+ require 'puppet/http/service/file_server'
25
+ require 'puppet/http/service/report'
21
26
  require 'puppet/http/session'
22
27
  require 'puppet/http/resolver'
28
+ require 'puppet/http/resolver/server_list'
23
29
  require 'puppet/http/resolver/settings'
24
30
  require 'puppet/http/resolver/srv'
25
31
  require 'puppet/http/client'
26
32
  require 'puppet/http/redirector'
27
33
  require 'puppet/http/retry_after_handler'
34
+ require 'puppet/http/external_client'
28
35
  end
29
36
  end
@@ -1,98 +1,323 @@
1
+ #
2
+ # @api private
3
+ #
4
+ # The client contains a pool of persistent HTTP connections and creates HTTP
5
+ # sessions.
6
+ #
1
7
  class Puppet::HTTP::Client
2
- def initialize(pool: Puppet::Network::HTTP::Pool.new, ssl_context: nil, redirect_limit: 10, retry_limit: 100)
8
+
9
+ # @api private
10
+ # @return [Puppet::Network::HTTP::Pool] the pool instance associated with
11
+ # this client
12
+ attr_reader :pool
13
+
14
+ #
15
+ # @api private
16
+ #
17
+ # Create a new http client instance. The client contains a pool of persistent
18
+ # HTTP connections and creates HTTP sessions.
19
+ #
20
+ # @param [Puppet::Network::HTTP::Pool] pool pool of persistent Net::HTTP
21
+ # connections
22
+ # @param [Puppet::SSL::SSLContext] ssl_context ssl context to be used for
23
+ # connections
24
+ # @param [Puppet::SSL::SSLContext] system_ssl_context the system ssl context
25
+ # used if :include_system_store is set to true
26
+ # @param [Integer] redirect_limit default number of HTTP redirections to allow
27
+ # in a given request. Can also be specified per-request.
28
+ # @param [Integer] retry_limit number of HTTP reties allowed in a given
29
+ # request
30
+ #
31
+ def initialize(pool: Puppet::Network::HTTP::Pool.new(Puppet[:http_keepalive_timeout]), ssl_context: nil, system_ssl_context: nil, redirect_limit: 10, retry_limit: 100)
3
32
  @pool = pool
4
33
  @default_headers = {
5
34
  'X-Puppet-Version' => Puppet.version,
6
35
  'User-Agent' => Puppet[:http_user_agent],
7
36
  }.freeze
8
37
  @default_ssl_context = ssl_context
9
- @redirector = Puppet::HTTP::Redirector.new(redirect_limit)
38
+ @default_system_ssl_context = system_ssl_context
39
+ @default_redirect_limit = redirect_limit
10
40
  @retry_after_handler = Puppet::HTTP::RetryAfterHandler.new(retry_limit, Puppet[:runinterval])
11
- @resolvers = build_resolvers
12
41
  end
13
42
 
43
+ #
44
+ # @api private
45
+ #
46
+ # Create a new HTTP session. A session is the object through which services
47
+ # may be connected to and accessed.
48
+ #
49
+ # @return [Puppet::HTTP::Session] the newly created HTTP session
50
+ #
14
51
  def create_session
15
- Puppet::HTTP::Session.new(self, @resolvers)
52
+ Puppet::HTTP::Session.new(self, build_resolvers)
16
53
  end
17
54
 
18
- def connect(uri, ssl_context: nil, &block)
19
- ctx = ssl_context ? ssl_context : default_ssl_context
55
+ #
56
+ # @api private
57
+ #
58
+ # Open a connection to the given URI
59
+ #
60
+ # @param [URI] uri the connection destination
61
+ # @param [Hash] options
62
+ # @option options [Puppet::SSL::SSLContext] :ssl_context (nil) ssl context to
63
+ # be used for connections
64
+ # @option options [Boolean] :include_system_store (false) if we should include
65
+ # the system store for connection
66
+ #
67
+ # @yield [Net::HTTP] If a block is given, yields an active http connection
68
+ # from the pool
69
+ #
70
+ def connect(uri, options: {}, &block)
71
+ start = Time.now
72
+ verifier = nil
73
+ connected = false
74
+
20
75
  site = Puppet::Network::HTTP::Site.from_uri(uri)
21
- verifier = Puppet::SSL::Verifier.new(site.host, ctx)
76
+ if site.use_ssl?
77
+ ssl_context = options.fetch(:ssl_context, nil)
78
+ include_system_store = options.fetch(:include_system_store, false)
79
+ ctx = resolve_ssl_context(ssl_context, include_system_store)
80
+ verifier = Puppet::SSL::Verifier.new(site.host, ctx)
81
+ end
22
82
 
23
83
  @pool.with_connection(site, verifier) do |http|
84
+ connected = true
24
85
  if block_given?
25
- handle_post_connect(uri, http, &block)
86
+ yield http
26
87
  end
27
88
  end
89
+ rescue Net::OpenTimeout => e
90
+ raise_error(_("Request to %{uri} timed out connect operation after %{elapsed} seconds") % {uri: uri, elapsed: elapsed(start)}, e, connected)
91
+ rescue Net::ReadTimeout => e
92
+ raise_error(_("Request to %{uri} timed out read operation after %{elapsed} seconds") % {uri: uri, elapsed: elapsed(start)}, e, connected)
93
+ rescue EOFError => e
94
+ raise_error(_("Request to %{uri} interrupted after %{elapsed} seconds") % {uri: uri, elapsed: elapsed(start)}, e, connected)
95
+ rescue Puppet::SSL::SSLError
96
+ raise
28
97
  rescue Puppet::HTTP::HTTPError
29
98
  raise
30
99
  rescue => e
31
- raise Puppet::HTTP::ConnectionError.new(_("Failed to connect to %{uri}: %{message}") % {uri: uri, message: e.message}, e)
100
+ raise_error(_("Request to %{uri} failed after %{elapsed} seconds: %{message}") %
101
+ {uri: uri, elapsed: elapsed(start), message: e.message}, e, connected)
32
102
  end
33
103
 
34
- def get(url, headers: {}, params: {}, ssl_context: nil, user: nil, password: nil, &block)
35
- query = encode_params(params)
36
- unless query.empty?
37
- url = url.dup
38
- url.query = query
39
- end
104
+ #
105
+ # @api private
106
+ #
107
+ # Submits a GET HTTP request to the given url
108
+ #
109
+ # @param [URI] url the location to submit the http request
110
+ # @param [Hash] headers merged with the default headers defined by the client
111
+ # @param [Hash] params encoded and set as the url query
112
+ # @param [Hash] options passed through to the request execution
113
+ # @option options [Puppet::SSL::SSLContext] :ssl_context (nil) ssl context to
114
+ # be used for connections
115
+ # @option options [Boolean] :include_system_store (false) if we should include
116
+ # the system store for connection
117
+ # @param options [Integer] :redirect_limit number of HTTP redirections to allow
118
+ # for this request.
119
+ #
120
+ # @yield [Puppet::HTTP::Response] if a block is given yields the response
121
+ #
122
+ # @return [String] if a block is not given, returns the response body
123
+ #
124
+ def get(url, headers: {}, params: {}, options: {}, &block)
125
+ url = encode_query(url, params)
40
126
 
41
127
  request = Net::HTTP::Get.new(url, @default_headers.merge(headers))
42
128
 
43
- execute_streaming(request, ssl_context: ssl_context, user: user, password: password) do |response|
129
+ execute_streaming(request, options: options) do |response|
44
130
  if block_given?
45
131
  yield response
46
132
  else
47
- response.read_body
133
+ response.body
48
134
  end
49
135
  end
50
136
  end
51
137
 
52
- def put(url, headers: {}, params: {}, content_type:, body:, ssl_context: nil, user: nil, password: nil)
53
- query = encode_params(params)
54
- unless query.empty?
55
- url = url.dup
56
- url.query = query
138
+ #
139
+ # @api private
140
+ #
141
+ # Submits a HEAD HTTP request to the given url
142
+ #
143
+ # @param [URI] url the location to submit the http request
144
+ # @param [Hash] headers merged with the default headers defined by the client
145
+ # @param [Hash] params encoded and set as the url query
146
+ # @param [Hash] options passed through to the request execution
147
+ # @option options [Puppet::SSL::SSLContext] :ssl_context (nil) ssl context to
148
+ # be used for connections
149
+ # @option options [Boolean] :include_system_store (false) if we should include
150
+ # the system store for connection
151
+ # @param options [Integer] :redirect_limit number of HTTP redirections to allow
152
+ # for this request.
153
+ #
154
+ # @return [String] the body of the request response
155
+ #
156
+ def head(url, headers: {}, params: {}, options: {})
157
+ url = encode_query(url, params)
158
+
159
+ request = Net::HTTP::Head.new(url, @default_headers.merge(headers))
160
+
161
+ execute_streaming(request, options: options) do |response|
162
+ response.body
57
163
  end
164
+ end
165
+
166
+ #
167
+ # @api private
168
+ #
169
+ # Submits a PUT HTTP request to the given url
170
+ #
171
+ # @param [URI] url the location to submit the http request
172
+ # @param [String] body the body of the PUT request
173
+ # @param [Hash] headers merged with the default headers defined by the client
174
+ # @param [Hash] params encoded and set as the url query
175
+ # @param [Hash] options passed through to the request execution
176
+ # @option options [String] :content_type the type of the body content
177
+ # @option options [Puppet::SSL::SSLContext] :ssl_context (nil) ssl context to
178
+ # be used for connections
179
+ # @option options [Boolean] :include_system_store (false) if we should include
180
+ # the system store for connection
181
+ # @param options [Integer] :redirect_limit number of HTTP redirections to allow
182
+ # for this request.
183
+ #
184
+ # @return [String] the body of the request response
185
+ #
186
+ def put(url, body, headers: {}, params: {}, options: {})
187
+ raise ArgumentError, "'put' requires a string 'body' argument" unless body.is_a?(String)
188
+ url = encode_query(url, params)
58
189
 
59
190
  request = Net::HTTP::Put.new(url, @default_headers.merge(headers))
60
191
  request.body = body
61
- request['Content-Length'] = body.bytesize
62
- request['Content-Type'] = content_type
192
+ request.content_length = body.bytesize
63
193
 
64
- execute_streaming(request, ssl_context: ssl_context, user: user, password: password) do |response|
65
- response.read_body
194
+ raise ArgumentError, "'put' requires a 'content-type' header" unless request['Content-Type']
195
+
196
+ execute_streaming(request, options: options) do |response|
197
+ response.body
66
198
  end
67
199
  end
68
200
 
201
+ #
202
+ # @api private
203
+ #
204
+ # Submits a POST HTTP request to the given url
205
+ #
206
+ # @param [URI] url the location to submit the http request
207
+ # @param [String] body the body of the POST request
208
+ # @param [Hash] headers merged with the default headers defined by the client
209
+ # @param [Hash] params encoded and set as the url query
210
+ # @param [Hash] options passed through to the request execution
211
+ # @option options [String] :content_type the type of the body content
212
+ # @option options [Puppet::SSL::SSLContext] :ssl_context (nil) ssl context to
213
+ # be used for connections
214
+ # @option options [Boolean] :include_system_store (false) if we should include
215
+ # the system store for connection
216
+ # @param options [Integer] :redirect_limit number of HTTP redirections to allow
217
+ # for this request.
218
+ #
219
+ # @return [String] the body of the request response
220
+ #
221
+ def post(url, body, headers: {}, params: {}, options: {}, &block)
222
+ raise ArgumentError, "'post' requires a string 'body' argument" unless body.is_a?(String)
223
+ url = encode_query(url, params)
224
+
225
+ request = Net::HTTP::Post.new(url, @default_headers.merge(headers))
226
+ request.body = body
227
+ request.content_length = body.bytesize
228
+
229
+ raise ArgumentError, "'post' requires a 'content-type' header" unless request['Content-Type']
230
+
231
+ execute_streaming(request, options: options) do |response|
232
+ if block_given?
233
+ yield response
234
+ else
235
+ response.body
236
+ end
237
+ end
238
+ end
239
+
240
+ #
241
+ # @api private
242
+ #
243
+ # Submits a DELETE HTTP request to the given url
244
+ #
245
+ # @param [URI] url the location to submit the http request
246
+ # @param [Hash] headers merged with the default headers defined by the client
247
+ # @param [Hash] params encoded and set as the url query
248
+ # @param [Hash] options options hash passed through to the request execution
249
+ # @option options [Puppet::SSL::SSLContext] :ssl_context (nil) ssl context to
250
+ # be used for connections
251
+ # @option options [Boolean] :include_system_store (false) if we should include
252
+ # the system store for connection
253
+ # @param options [Integer] :redirect_limit number of HTTP redirections to allow
254
+ # for this request.
255
+ #
256
+ # @return [String] the body of the request response
257
+ #
258
+ def delete(url, headers: {}, params: {}, options: {})
259
+ url = encode_query(url, params)
260
+
261
+ request = Net::HTTP::Delete.new(url, @default_headers.merge(headers))
262
+
263
+ execute_streaming(request, options: options) do |response|
264
+ response.body
265
+ end
266
+ end
267
+
268
+ #
269
+ # @api private
270
+ #
271
+ # Close persistent connections in the pool
272
+ #
69
273
  def close
70
274
  @pool.close
71
275
  end
72
276
 
277
+ protected
278
+
279
+ def encode_query(url, params)
280
+ return url if params.empty?
281
+
282
+ url = url.dup
283
+ url.query = encode_params(params)
284
+ url
285
+ end
286
+
73
287
  private
74
288
 
75
- def execute_streaming(request, ssl_context:, user: nil, password: nil, &block)
289
+ def execute_streaming(request, options: {}, &block)
290
+ redirector = Puppet::HTTP::Redirector.new(options.fetch(:redirect_limit, @default_redirect_limit))
291
+
292
+ basic_auth = options.fetch(:basic_auth, nil)
293
+
76
294
  redirects = 0
77
295
  retries = 0
296
+ response = nil
297
+ done = false
78
298
 
79
- loop do
80
- connect(request.uri, ssl_context: ssl_context) do |http|
81
- apply_auth(request, user, password)
299
+ while !done do
300
+ connect(request.uri, options: options) do |http|
301
+ apply_auth(request, basic_auth)
82
302
 
303
+ # don't call return within the `request` block
83
304
  http.request(request) do |nethttp|
84
- response = Puppet::HTTP::Response.new(nethttp)
305
+ response = Puppet::HTTP::Response.new(nethttp, request.uri)
85
306
  begin
86
307
  Puppet.debug("HTTP #{request.method.upcase} #{request.uri} returned #{response.code} #{response.reason}")
87
308
 
88
- if @redirector.redirect?(request, response)
89
- request = @redirector.redirect_to(request, response, redirects)
309
+ if redirector.redirect?(request, response)
310
+ request = redirector.redirect_to(request, response, redirects)
90
311
  redirects += 1
91
312
  next
92
313
  elsif @retry_after_handler.retry_after?(request, response)
93
314
  interval = @retry_after_handler.retry_after_interval(request, response, retries)
94
315
  retries += 1
95
316
  if interval
317
+ if http.started?
318
+ Puppet.debug("Closing connection for #{Puppet::Network::HTTP::Site.from_uri(request.uri)}")
319
+ http.finish
320
+ end
96
321
  Puppet.warning(_("Sleeping for %{interval} seconds before retrying the request") % { interval: interval })
97
322
  ::Kernel.sleep(interval)
98
323
  next
@@ -104,42 +329,86 @@ class Puppet::HTTP::Client
104
329
  response.drain
105
330
  end
106
331
 
107
- return response
332
+ done = true
108
333
  end
109
334
  end
110
335
  end
336
+
337
+ response
338
+ end
339
+
340
+ def expand_into_parameters(data)
341
+ data.inject([]) do |params, key_value|
342
+ key, value = key_value
343
+
344
+ expanded_value = case value
345
+ when Array
346
+ value.collect { |val| [key, val] }
347
+ else
348
+ [key_value]
349
+ end
350
+
351
+ params.concat(expand_primitive_types_into_parameters(expanded_value))
352
+ end
353
+ end
354
+
355
+ def expand_primitive_types_into_parameters(data)
356
+ data.inject([]) do |params, key_value|
357
+ key, value = key_value
358
+ case value
359
+ when nil
360
+ params
361
+ when true, false, String, Symbol, Integer, Float
362
+ params << [key, value]
363
+ else
364
+ raise Puppet::HTTP::SerializationError, _("HTTP REST queries cannot handle values of type '%{klass}'") % { klass: value.class }
365
+ end
366
+ end
111
367
  end
112
368
 
113
369
  def encode_params(params)
370
+ params = expand_into_parameters(params)
114
371
  params.map do |key, value|
115
372
  "#{key}=#{Puppet::Util.uri_query_encode(value.to_s)}"
116
373
  end.join('&')
117
374
  end
118
375
 
119
- def handle_post_connect(uri, http, &block)
120
- start = Time.now
121
- yield http
122
- rescue Puppet::HTTP::HTTPError
123
- raise
124
- rescue EOFError => e
125
- raise Puppet::HTTP::HTTPError.new(_("Request to %{uri} interrupted after %{elapsed} seconds") % {uri: uri, elapsed: elapsed(start)}, e)
126
- rescue Timeout::Error => e
127
- raise Puppet::HTTP::HTTPError.new(_("Request to %{uri} timed out after %{elapsed} seconds") % {uri: uri, elapsed: elapsed(start)}, e)
128
- rescue => e
129
- raise Puppet::HTTP::HTTPError.new(_("Request to %{uri} failed after %{elapsed} seconds: %{message}") % {uri: uri, elapsed: elapsed(start), message: e.message}, e)
130
- end
131
-
132
376
  def elapsed(start)
133
377
  (Time.now - start).to_f.round(3)
134
378
  end
135
379
 
136
- def default_ssl_context
137
- @default_ssl_context || Puppet.lookup(:ssl_context)
380
+ def raise_error(message, cause, connected)
381
+ if connected
382
+ raise Puppet::HTTP::HTTPError.new(message, cause)
383
+ else
384
+ raise Puppet::HTTP::ConnectionError.new(message, cause)
385
+ end
386
+ end
387
+
388
+ def resolve_ssl_context(ssl_context, include_system_store)
389
+ if ssl_context
390
+ raise Puppet::HTTP::HTTPError, "The ssl_context and include_system_store parameters are mutually exclusive" if include_system_store
391
+ ssl_context
392
+ elsif include_system_store
393
+ system_ssl_context
394
+ else
395
+ @default_ssl_context || Puppet.lookup(:ssl_context)
396
+ end
397
+ end
398
+
399
+ def system_ssl_context
400
+ return @default_system_ssl_context if @default_system_ssl_context
401
+
402
+ cert_provider = Puppet::X509::CertProvider.new
403
+ cacerts = cert_provider.load_cacerts || []
404
+
405
+ ssl = Puppet::SSL::SSLProvider.new
406
+ @default_system_ssl_context = ssl.create_system_context(cacerts: cacerts)
138
407
  end
139
408
 
140
- def apply_auth(request, user, password)
141
- if user && password
142
- request.basic_auth(user, password)
409
+ def apply_auth(request, basic_auth)
410
+ if basic_auth
411
+ request.basic_auth(basic_auth[:user], basic_auth[:password])
143
412
  end
144
413
  end
145
414
 
@@ -147,10 +416,28 @@ class Puppet::HTTP::Client
147
416
  resolvers = []
148
417
 
149
418
  if Puppet[:use_srv_records]
150
- resolvers << Puppet::HTTP::Resolver::SRV.new(domain: Puppet[:srv_domain])
419
+ resolvers << Puppet::HTTP::Resolver::SRV.new(self, domain: Puppet[:srv_domain])
151
420
  end
152
421
 
153
- resolvers << Puppet::HTTP::Resolver::Settings.new
422
+ server_list_setting = Puppet.settings.setting(:server_list)
423
+ if server_list_setting.value && !server_list_setting.value.empty?
424
+ # use server list to resolve all services
425
+ services = Puppet::HTTP::Service::SERVICE_NAMES.dup
426
+
427
+ # except if it's been explicitly set
428
+ if Puppet.settings.set_by_config?(:ca_server)
429
+ services.delete(:ca)
430
+ end
431
+
432
+ if Puppet.settings.set_by_config?(:report_server)
433
+ services.delete(:report)
434
+ end
435
+
436
+ resolvers << Puppet::HTTP::Resolver::ServerList.new(self, server_list_setting: server_list_setting, default_port: Puppet[:masterport], services: services)
437
+ end
438
+
439
+ resolvers << Puppet::HTTP::Resolver::Settings.new(self)
440
+
154
441
  resolvers.freeze
155
442
  end
156
443
  end