puppet 6.12.0-x64-mingw32 → 6.17.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 (412) 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 +39 -36
  6. data/README.md +18 -25
  7. data/ext/project_data.yaml +1 -1
  8. data/ext/windows/service/daemon.rb +3 -3
  9. data/lib/puppet.rb +52 -13
  10. data/lib/puppet/agent.rb +20 -14
  11. data/lib/puppet/application/agent.rb +26 -17
  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/plugin.rb +1 -0
  16. data/lib/puppet/application/resource.rb +1 -1
  17. data/lib/puppet/application/ssl.rb +4 -4
  18. data/lib/puppet/configurer.rb +65 -69
  19. data/lib/puppet/configurer/plugin_handler.rb +10 -1
  20. data/lib/puppet/confine.rb +1 -1
  21. data/lib/puppet/context/trusted_information.rb +14 -8
  22. data/lib/puppet/daemon.rb +13 -27
  23. data/lib/puppet/defaults.rb +154 -58
  24. data/lib/puppet/environments.rb +27 -20
  25. data/lib/puppet/face/facts.rb +8 -5
  26. data/lib/puppet/face/help.rb +29 -3
  27. data/lib/puppet/face/module/search.rb +5 -0
  28. data/lib/puppet/face/plugin.rb +2 -2
  29. data/lib/puppet/file_serving/http_metadata.rb +14 -2
  30. data/lib/puppet/file_serving/metadata.rb +4 -1
  31. data/lib/puppet/file_serving/terminus_selector.rb +7 -8
  32. data/lib/puppet/file_system/file_impl.rb +14 -10
  33. data/lib/puppet/file_system/memory_file.rb +6 -0
  34. data/lib/puppet/file_system/memory_impl.rb +13 -0
  35. data/lib/puppet/file_system/uniquefile.rb +12 -16
  36. data/lib/puppet/file_system/windows.rb +7 -10
  37. data/lib/puppet/forge.rb +1 -1
  38. data/lib/puppet/forge/cache.rb +1 -1
  39. data/lib/puppet/forge/repository.rb +4 -7
  40. data/lib/puppet/functions/call.rb +1 -1
  41. data/lib/puppet/functions/eyaml_lookup_key.rb +13 -8
  42. data/lib/puppet/functions/filter.rb +1 -0
  43. data/lib/puppet/functions/reduce.rb +2 -4
  44. data/lib/puppet/http.rb +5 -0
  45. data/lib/puppet/http/client.rb +293 -73
  46. data/lib/puppet/http/errors.rb +2 -0
  47. data/lib/puppet/http/external_client.rb +90 -0
  48. data/lib/puppet/http/redirector.rb +43 -7
  49. data/lib/puppet/http/resolver.rb +46 -3
  50. data/lib/puppet/http/resolver/server_list.rb +76 -16
  51. data/lib/puppet/http/resolver/settings.rb +23 -3
  52. data/lib/puppet/http/resolver/srv.rb +29 -3
  53. data/lib/puppet/http/response.rb +87 -1
  54. data/lib/puppet/http/retry_after_handler.rb +39 -0
  55. data/lib/puppet/http/service.rb +151 -7
  56. data/lib/puppet/http/service/ca.rb +76 -14
  57. data/lib/puppet/http/service/compiler.rb +319 -0
  58. data/lib/puppet/http/service/file_server.rb +206 -0
  59. data/lib/puppet/http/service/report.rb +49 -23
  60. data/lib/puppet/http/session.rb +103 -7
  61. data/lib/puppet/indirector.rb +1 -1
  62. data/lib/puppet/indirector/catalog/compiler.rb +10 -0
  63. data/lib/puppet/indirector/catalog/rest.rb +34 -0
  64. data/lib/puppet/indirector/facts/rest.rb +42 -0
  65. data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
  66. data/lib/puppet/indirector/file_bucket_file/rest.rb +48 -0
  67. data/lib/puppet/indirector/file_content/http.rb +5 -0
  68. data/lib/puppet/indirector/file_content/rest.rb +30 -0
  69. data/lib/puppet/indirector/file_metadata/http.rb +27 -8
  70. data/lib/puppet/indirector/file_metadata/rest.rb +52 -0
  71. data/lib/puppet/indirector/json.rb +1 -1
  72. data/lib/puppet/indirector/msgpack.rb +1 -1
  73. data/lib/puppet/indirector/node/rest.rb +24 -0
  74. data/lib/puppet/indirector/report/rest.rb +19 -0
  75. data/lib/puppet/indirector/report/yaml.rb +23 -0
  76. data/lib/puppet/indirector/request.rb +1 -1
  77. data/lib/puppet/indirector/rest.rb +12 -0
  78. data/lib/puppet/indirector/status/rest.rb +18 -0
  79. data/lib/puppet/loaders.rb +6 -0
  80. data/lib/puppet/metatype/manager.rb +80 -80
  81. data/lib/puppet/network/http/api/indirected_routes.rb +1 -1
  82. data/lib/puppet/network/http/api/master/v3/environment.rb +3 -0
  83. data/lib/puppet/network/http/base_pool.rb +7 -2
  84. data/lib/puppet/network/http/compression.rb +7 -0
  85. data/lib/puppet/network/http/connection.rb +6 -0
  86. data/lib/puppet/network/http/connection_adapter.rb +184 -0
  87. data/lib/puppet/network/http/nocache_pool.rb +2 -0
  88. data/lib/puppet/network/http/pool.rb +13 -6
  89. data/lib/puppet/network/http_pool.rb +2 -1
  90. data/lib/puppet/node/environment.rb +11 -1
  91. data/lib/puppet/pal/catalog_compiler.rb +5 -0
  92. data/lib/puppet/pal/pal_impl.rb +4 -29
  93. data/lib/puppet/parser/ast/leaf.rb +5 -5
  94. data/lib/puppet/parser/ast/pops_bridge.rb +6 -15
  95. data/lib/puppet/parser/compiler.rb +43 -33
  96. data/lib/puppet/parser/compiler/catalog_validator/env_relationship_validator.rb +2 -0
  97. data/lib/puppet/parser/compiler/catalog_validator/site_validator.rb +2 -0
  98. data/lib/puppet/parser/environment_compiler.rb +4 -1
  99. data/lib/puppet/parser/functions.rb +18 -13
  100. data/lib/puppet/parser/functions/filter.rb +1 -0
  101. data/lib/puppet/parser/resource.rb +3 -2
  102. data/lib/puppet/parser/resource/param.rb +6 -0
  103. data/lib/puppet/pops/evaluator/access_operator.rb +2 -2
  104. data/lib/puppet/pops/evaluator/evaluator_impl.rb +6 -6
  105. data/lib/puppet/pops/issues.rb +5 -0
  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/parser/evaluating_parser.rb +5 -7
  109. data/lib/puppet/pops/resource/resource_type_impl.rb +2 -0
  110. data/lib/puppet/pops/types/p_object_type_extension.rb +10 -0
  111. data/lib/puppet/pops/types/type_calculator.rb +24 -0
  112. data/lib/puppet/pops/validation/checker4_0.rb +11 -1
  113. data/lib/puppet/pops/validation/tasks_checker.rb +5 -1
  114. data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -0
  115. data/lib/puppet/provider/aix_object.rb +4 -2
  116. data/lib/puppet/provider/group/aix.rb +1 -0
  117. data/lib/puppet/provider/group/groupadd.rb +57 -24
  118. data/lib/puppet/provider/group/windows_adsi.rb +3 -3
  119. data/lib/puppet/provider/package/aix.rb +17 -2
  120. data/lib/puppet/provider/package/apt.rb +78 -4
  121. data/lib/puppet/provider/package/aptitude.rb +1 -1
  122. data/lib/puppet/provider/package/dnfmodule.rb +69 -15
  123. data/lib/puppet/provider/package/dpkg.rb +14 -7
  124. data/lib/puppet/provider/package/fink.rb +20 -3
  125. data/lib/puppet/provider/package/gem.rb +41 -7
  126. data/lib/puppet/provider/package/openbsd.rb +13 -1
  127. data/lib/puppet/provider/package/pacman.rb +2 -5
  128. data/lib/puppet/provider/package/pip.rb +143 -48
  129. data/lib/puppet/provider/package/pip3.rb +0 -2
  130. data/lib/puppet/provider/package/pkg.rb +18 -5
  131. data/lib/puppet/provider/package/pkgdmg.rb +1 -1
  132. data/lib/puppet/provider/package/pkgng.rb +16 -4
  133. data/lib/puppet/provider/package/portage.rb +2 -2
  134. data/lib/puppet/provider/package/puppet_gem.rb +6 -2
  135. data/lib/puppet/provider/package/rpm.rb +6 -213
  136. data/lib/puppet/provider/package/yum.rb +109 -25
  137. data/lib/puppet/provider/package/zypper.rb +59 -1
  138. data/lib/puppet/provider/service/systemd.rb +22 -4
  139. data/lib/puppet/provider/service/windows.rb +23 -7
  140. data/lib/puppet/provider/user/aix.rb +1 -0
  141. data/lib/puppet/provider/user/directoryservice.rb +30 -5
  142. data/lib/puppet/provider/user/useradd.rb +22 -12
  143. data/lib/puppet/reports/http.rb +15 -9
  144. data/lib/puppet/reports/store.rb +1 -1
  145. data/lib/puppet/resource.rb +2 -1
  146. data/lib/puppet/resource/type.rb +8 -0
  147. data/lib/puppet/resource/type_collection.rb +20 -16
  148. data/lib/puppet/runtime.rb +31 -1
  149. data/lib/puppet/settings.rb +4 -0
  150. data/lib/puppet/settings/http_extra_headers_setting.rb +25 -0
  151. data/lib/puppet/ssl.rb +1 -0
  152. data/lib/puppet/ssl/certificate.rb +2 -1
  153. data/lib/puppet/ssl/host.rb +4 -4
  154. data/lib/puppet/ssl/oids.rb +1 -0
  155. data/lib/puppet/ssl/ssl_context.rb +2 -2
  156. data/lib/puppet/ssl/ssl_provider.rb +20 -1
  157. data/lib/puppet/ssl/state_machine.rb +81 -35
  158. data/lib/puppet/ssl/verifier_adapter.rb +9 -1
  159. data/lib/puppet/test/test_helper.rb +15 -11
  160. data/lib/puppet/transaction/report.rb +2 -2
  161. data/lib/puppet/transaction/resource_harness.rb +1 -1
  162. data/lib/puppet/trusted_external.rb +29 -1
  163. data/lib/puppet/type.rb +18 -6
  164. data/lib/puppet/type/file.rb +51 -13
  165. data/lib/puppet/type/file/checksum.rb +4 -4
  166. data/lib/puppet/type/file/source.rb +51 -60
  167. data/lib/puppet/type/group.rb +2 -2
  168. data/lib/puppet/type/package.rb +102 -10
  169. data/lib/puppet/type/service.rb +55 -8
  170. data/lib/puppet/type/user.rb +3 -28
  171. data/lib/puppet/util.rb +39 -15
  172. data/lib/puppet/util/at_fork.rb +1 -1
  173. data/lib/puppet/util/autoload.rb +4 -18
  174. data/lib/puppet/util/checksums.rb +19 -4
  175. data/lib/puppet/util/fileparsing.rb +2 -2
  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/package/version/debian.rb +175 -0
  179. data/lib/puppet/util/package/version/gem.rb +15 -0
  180. data/lib/puppet/util/package/version/pip.rb +167 -0
  181. data/lib/puppet/util/package/version/range.rb +53 -0
  182. data/lib/puppet/util/package/version/range/eq.rb +14 -0
  183. data/lib/puppet/util/package/version/range/gt.rb +14 -0
  184. data/lib/puppet/util/package/version/range/gt_eq.rb +14 -0
  185. data/lib/puppet/util/package/version/range/lt.rb +14 -0
  186. data/lib/puppet/util/package/version/range/lt_eq.rb +14 -0
  187. data/lib/puppet/util/package/version/range/min_max.rb +21 -0
  188. data/lib/puppet/util/package/version/range/simple.rb +11 -0
  189. data/lib/puppet/util/package/version/rpm.rb +73 -0
  190. data/lib/puppet/util/pidlock.rb +36 -10
  191. data/lib/puppet/util/platform.rb +5 -0
  192. data/lib/puppet/util/plist.rb +6 -0
  193. data/lib/puppet/util/provider_features.rb +1 -1
  194. data/lib/puppet/util/reference.rb +1 -1
  195. data/lib/puppet/util/rpm_compare.rb +193 -0
  196. data/lib/puppet/util/storage.rb +0 -1
  197. data/lib/puppet/util/windows/adsi.rb +2 -2
  198. data/lib/puppet/util/windows/api_types.rb +45 -32
  199. data/lib/puppet/util/windows/eventlog.rb +1 -6
  200. data/lib/puppet/util/windows/principal.rb +8 -6
  201. data/lib/puppet/util/windows/process.rb +15 -14
  202. data/lib/puppet/util/windows/registry.rb +11 -11
  203. data/lib/puppet/util/windows/security.rb +1 -0
  204. data/lib/puppet/util/windows/service.rb +43 -26
  205. data/lib/puppet/util/windows/sid.rb +3 -3
  206. data/lib/puppet/util/windows/user.rb +23 -8
  207. data/lib/puppet/util/yaml.rb +1 -1
  208. data/lib/puppet/version.rb +1 -1
  209. data/locales/puppet.pot +707 -574
  210. data/man/man5/puppet.conf.5 +74 -14
  211. data/man/man8/puppet-agent.8 +7 -7
  212. data/man/man8/puppet-apply.8 +1 -1
  213. data/man/man8/puppet-catalog.8 +1 -1
  214. data/man/man8/puppet-config.8 +1 -1
  215. data/man/man8/puppet-describe.8 +1 -1
  216. data/man/man8/puppet-device.8 +2 -2
  217. data/man/man8/puppet-doc.8 +1 -1
  218. data/man/man8/puppet-epp.8 +1 -1
  219. data/man/man8/puppet-facts.8 +1 -1
  220. data/man/man8/puppet-filebucket.8 +17 -2
  221. data/man/man8/puppet-generate.8 +1 -1
  222. data/man/man8/puppet-help.8 +6 -3
  223. data/man/man8/puppet-key.8 +1 -1
  224. data/man/man8/puppet-lookup.8 +1 -1
  225. data/man/man8/puppet-man.8 +1 -1
  226. data/man/man8/puppet-module.8 +4 -1
  227. data/man/man8/puppet-node.8 +1 -1
  228. data/man/man8/puppet-parser.8 +1 -1
  229. data/man/man8/puppet-plugin.8 +1 -1
  230. data/man/man8/puppet-report.8 +1 -1
  231. data/man/man8/puppet-resource.8 +1 -1
  232. data/man/man8/puppet-script.8 +1 -1
  233. data/man/man8/puppet-ssl.8 +2 -2
  234. data/man/man8/puppet-status.8 +1 -1
  235. data/man/man8/puppet.8 +2 -2
  236. data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +67 -0
  237. data/spec/fixtures/ssl/unknown-127.0.0.1.pem +48 -0
  238. data/spec/fixtures/ssl/unknown-ca-key.pem +67 -0
  239. data/spec/fixtures/ssl/unknown-ca.pem +59 -0
  240. data/spec/fixtures/unit/provider/package/dnfmodule/{dnf-module-list-installed.txt → dnf-module-list.txt} +8 -0
  241. data/spec/fixtures/unit/provider/package/pkgng/pkg.version +2 -0
  242. data/spec/fixtures/unit/provider/package/yum/yum-check-update-subscription-manager.txt +9 -0
  243. data/spec/fixtures/unit/provider/package/zypper/zypper-search-uninstalled.out +13 -0
  244. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services +9 -0
  245. 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
  246. 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
  247. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_update_if_content_differs_on_disk.yml +1 -106
  248. 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
  249. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_no_header_specified.yml +1 -98
  250. 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
  251. 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
  252. data/spec/integration/application/agent_spec.rb +483 -0
  253. data/spec/integration/application/apply_spec.rb +132 -3
  254. data/spec/integration/application/filebucket_spec.rb +190 -0
  255. data/spec/integration/application/plugin_spec.rb +73 -0
  256. data/spec/integration/configurer_spec.rb +26 -7
  257. data/spec/integration/defaults_spec.rb +1 -2
  258. data/spec/integration/http/client_spec.rb +47 -37
  259. data/spec/integration/indirector/facts/facter_spec.rb +4 -0
  260. data/spec/integration/indirector/report/yaml.rb +83 -0
  261. data/spec/integration/module_tool/forge_spec.rb +2 -15
  262. data/spec/integration/network/http_pool_spec.rb +93 -20
  263. data/spec/integration/node/environment_spec.rb +15 -0
  264. data/spec/integration/parser/compiler_spec.rb +11 -0
  265. data/spec/integration/type/file_spec.rb +1 -1
  266. data/spec/integration/util/windows/adsi_spec.rb +6 -1
  267. data/spec/integration/util/windows/registry_spec.rb +7 -7
  268. data/spec/integration/util/windows/user_spec.rb +40 -5
  269. data/spec/lib/puppet/test_ca.rb +2 -2
  270. data/spec/lib/puppet_spec/https.rb +16 -7
  271. data/spec/lib/puppet_spec/puppetserver.rb +119 -0
  272. data/spec/shared_contexts/https.rb +29 -0
  273. data/spec/unit/agent_spec.rb +80 -26
  274. data/spec/unit/application/agent_spec.rb +9 -5
  275. data/spec/unit/application/apply_spec.rb +2 -12
  276. data/spec/unit/application/describe_spec.rb +88 -50
  277. data/spec/unit/application/device_spec.rb +2 -2
  278. data/spec/unit/application/filebucket_spec.rb +22 -2
  279. data/spec/unit/application/resource_spec.rb +2 -2
  280. data/spec/unit/configurer/fact_handler_spec.rb +4 -8
  281. data/spec/unit/configurer/plugin_handler_spec.rb +36 -19
  282. data/spec/unit/configurer_spec.rb +17 -18
  283. data/spec/unit/context/trusted_information_spec.rb +25 -2
  284. data/spec/unit/daemon_spec.rb +5 -64
  285. data/spec/unit/defaults_spec.rb +25 -2
  286. data/spec/unit/environments_spec.rb +65 -28
  287. data/spec/unit/face/facts_spec.rb +24 -20
  288. data/spec/unit/face/module/search_spec.rb +17 -0
  289. data/spec/unit/face/plugin_spec.rb +12 -10
  290. data/spec/unit/file_serving/http_metadata_spec.rb +37 -14
  291. data/spec/unit/file_serving/terminus_selector_spec.rb +45 -26
  292. data/spec/unit/file_system/uniquefile_spec.rb +11 -0
  293. data/spec/unit/file_system_spec.rb +26 -2
  294. data/spec/unit/functions/lookup_spec.rb +13 -0
  295. data/spec/unit/http/client_spec.rb +327 -35
  296. data/spec/unit/http/external_client_spec.rb +201 -0
  297. data/spec/unit/http/resolver_spec.rb +34 -2
  298. data/spec/unit/http/response_spec.rb +75 -0
  299. data/spec/unit/http/service/ca_spec.rb +53 -11
  300. data/spec/unit/http/service/compiler_spec.rb +627 -0
  301. data/spec/unit/http/service/file_server_spec.rb +308 -0
  302. data/spec/unit/http/service/report_spec.rb +27 -9
  303. data/spec/unit/http/service_spec.rb +98 -5
  304. data/spec/unit/http/session_spec.rb +190 -7
  305. data/spec/unit/indirector/catalog/compiler_spec.rb +47 -29
  306. data/spec/unit/indirector/catalog/rest_spec.rb +59 -2
  307. data/spec/unit/indirector/facts/rest_spec.rb +79 -24
  308. data/spec/unit/indirector/file_bucket_file/rest_spec.rb +82 -2
  309. data/spec/unit/indirector/file_content/rest_spec.rb +53 -2
  310. data/spec/unit/indirector/file_metadata/http_spec.rb +194 -0
  311. data/spec/unit/indirector/file_metadata/rest_spec.rb +110 -2
  312. data/spec/unit/indirector/node/rest_spec.rb +57 -2
  313. data/spec/unit/indirector/report/rest_spec.rb +58 -51
  314. data/spec/unit/indirector/request_spec.rb +1 -1
  315. data/spec/unit/indirector/resource/ral_spec.rb +7 -8
  316. data/spec/unit/indirector/rest_spec.rb +13 -0
  317. data/spec/unit/indirector/status/rest_spec.rb +43 -2
  318. data/spec/unit/interface_spec.rb +3 -3
  319. data/spec/unit/network/http/api/indirected_routes_spec.rb +2 -1
  320. data/spec/unit/network/http/connection_spec.rb +559 -175
  321. data/spec/unit/network/http/nocache_pool_spec.rb +25 -3
  322. data/spec/unit/network/http/pool_spec.rb +89 -11
  323. data/spec/unit/network/http_pool_spec.rb +63 -57
  324. data/spec/unit/network/http_spec.rb +1 -1
  325. data/spec/unit/node/environment_spec.rb +16 -0
  326. data/spec/unit/node/facts_spec.rb +2 -1
  327. data/spec/unit/node_spec.rb +7 -4
  328. data/spec/unit/parser/ast/block_expression_spec.rb +1 -1
  329. data/spec/unit/parser/environment_compiler_spec.rb +7 -0
  330. data/spec/unit/parser/scope_spec.rb +1 -1
  331. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +15 -1
  332. data/spec/unit/pops/loaders/loaders_spec.rb +1 -1
  333. data/spec/unit/pops/serialization/to_from_hr_spec.rb +6 -1
  334. data/spec/unit/pops/types/type_calculator_spec.rb +1 -11
  335. data/spec/unit/pops/validator/validator_spec.rb +7 -2
  336. data/spec/unit/provider/aix_object_spec.rb +16 -2
  337. data/spec/unit/provider/group/groupadd_spec.rb +181 -56
  338. data/spec/unit/provider/group/windows_adsi_spec.rb +43 -10
  339. data/spec/unit/provider/package/aix_spec.rb +29 -0
  340. data/spec/unit/provider/package/apt_spec.rb +43 -2
  341. data/spec/unit/provider/package/aptitude_spec.rb +1 -0
  342. data/spec/unit/provider/package/dnfmodule_spec.rb +76 -15
  343. data/spec/unit/provider/package/dpkg_spec.rb +28 -6
  344. data/spec/unit/provider/package/gem_spec.rb +40 -0
  345. data/spec/unit/provider/package/openbsd_spec.rb +17 -0
  346. data/spec/unit/provider/package/pacman_spec.rb +6 -21
  347. data/spec/unit/provider/package/pip_spec.rb +68 -19
  348. data/spec/unit/provider/package/pkg_spec.rb +15 -1
  349. data/spec/unit/provider/package/pkgdmg_spec.rb +1 -1
  350. data/spec/unit/provider/package/pkgng_spec.rb +38 -0
  351. data/spec/unit/provider/package/portage_spec.rb +5 -0
  352. data/spec/unit/provider/package/puppet_gem_spec.rb +8 -0
  353. data/spec/unit/provider/package/rpm_spec.rb +0 -212
  354. data/spec/unit/provider/package/yum_spec.rb +292 -0
  355. data/spec/unit/provider/package/zypper_spec.rb +84 -0
  356. data/spec/unit/provider/service/init_spec.rb +1 -0
  357. data/spec/unit/provider/service/openbsd_spec.rb +9 -0
  358. data/spec/unit/provider/service/openwrt_spec.rb +1 -0
  359. data/spec/unit/provider/service/redhat_spec.rb +9 -0
  360. data/spec/unit/provider/service/systemd_spec.rb +92 -12
  361. data/spec/unit/provider/service/windows_spec.rb +22 -14
  362. data/spec/unit/provider/user/directoryservice_spec.rb +41 -0
  363. data/spec/unit/provider/user/openbsd_spec.rb +1 -0
  364. data/spec/unit/provider/user/useradd_spec.rb +43 -24
  365. data/spec/unit/provider/user/windows_adsi_spec.rb +3 -3
  366. data/spec/unit/puppet_pal_2pec.rb +0 -26
  367. data/spec/unit/puppet_pal_catalog_spec.rb +46 -0
  368. data/spec/unit/puppet_spec.rb +47 -0
  369. data/spec/unit/reports/http_spec.rb +70 -52
  370. data/spec/unit/resource_spec.rb +3 -3
  371. data/spec/unit/settings/autosign_setting_spec.rb +1 -1
  372. data/spec/unit/settings/http_extra_headers_spec.rb +64 -0
  373. data/spec/unit/ssl/certificate_spec.rb +7 -0
  374. data/spec/unit/ssl/host_spec.rb +4 -2
  375. data/spec/unit/ssl/oids_spec.rb +1 -0
  376. data/spec/unit/ssl/ssl_provider_spec.rb +69 -43
  377. data/spec/unit/ssl/state_machine_spec.rb +99 -13
  378. data/spec/unit/test/test_helper_spec.rb +17 -0
  379. data/spec/unit/transaction/persistence_spec.rb +1 -10
  380. data/spec/unit/transaction/report_spec.rb +5 -1
  381. data/spec/unit/transaction_spec.rb +0 -2
  382. data/spec/unit/type/file/ensure_spec.rb +1 -2
  383. data/spec/unit/type/file/source_spec.rb +89 -38
  384. data/spec/unit/type/file_spec.rb +122 -96
  385. data/spec/unit/type/package_spec.rb +8 -0
  386. data/spec/unit/type/service_spec.rb +185 -8
  387. data/spec/unit/type/user_spec.rb +1 -2
  388. data/spec/unit/type_spec.rb +50 -0
  389. data/spec/unit/util/at_fork_spec.rb +3 -2
  390. data/spec/unit/util/autoload_spec.rb +2 -1
  391. data/spec/unit/util/checksums_spec.rb +16 -0
  392. data/spec/unit/util/log/destinations_spec.rb +1 -29
  393. data/spec/unit/util/package/version/debian_spec.rb +83 -0
  394. data/spec/unit/util/package/version/pip_spec.rb +464 -0
  395. data/spec/unit/util/package/version/range_spec.rb +175 -0
  396. data/spec/unit/util/package/version/rpm_spec.rb +121 -0
  397. data/spec/unit/util/pidlock_spec.rb +112 -42
  398. data/spec/unit/util/plist_spec.rb +20 -0
  399. data/spec/unit/util/rpm_compare_spec.rb +196 -0
  400. data/spec/unit/util/storage_spec.rb +1 -8
  401. data/spec/unit/util/windows/adsi_spec.rb +4 -4
  402. data/spec/unit/util/windows/api_types_spec.rb +104 -40
  403. data/spec/unit/util/windows/service_spec.rb +4 -4
  404. data/spec/unit/util/windows/sid_spec.rb +2 -2
  405. data/spec/unit/util_spec.rb +3 -3
  406. data/spec/unit/x509/cert_provider_spec.rb +1 -1
  407. data/tasks/generate_cert_fixtures.rake +15 -1
  408. data/tasks/manpages.rake +5 -35
  409. metadata +73 -12
  410. data/COMMITTERS.md +0 -244
  411. data/spec/integration/faces/plugin_spec.rb +0 -61
  412. data/spec/integration/test/test_helper_spec.rb +0 -31
@@ -180,7 +180,7 @@ describe Puppet::Interface do
180
180
  display_global_options "modulepath"
181
181
  end
182
182
  end
183
- face.display_global_options =~ ["environment"]
183
+ expect(face.display_global_options).to match(["environment"])
184
184
  end
185
185
 
186
186
  it "should not fail when a face d_g_o duplicates an action d_g_o" do
@@ -200,8 +200,8 @@ describe Puppet::Interface do
200
200
  action :foo do when_invoked {|_| true} ; display_global_options "environment" end
201
201
  action :bar do when_invoked {|_| true} ; display_global_options "environment" end
202
202
  end
203
- face.get_action(:foo).display_global_options =~ ["environment"]
204
- face.get_action(:bar).display_global_options =~ ["environment"]
203
+ expect(face.get_action(:foo).display_global_options).to match(["environment"])
204
+ expect(face.get_action(:bar).display_global_options).to match(["environment"])
205
205
  end
206
206
 
207
207
  end
@@ -344,7 +344,8 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
344
344
 
345
345
  expect {
346
346
  handler.call(request, response)
347
- }.to raise_error(Puppet::Network::HTTP::Error::HTTPNotAcceptableError, /No supported formats are acceptable/)
347
+ }.to raise_error(Puppet::Network::HTTP::Error::HTTPNotAcceptableError,
348
+ %r{No supported formats are acceptable \(Accept: application/json, text/pson\)})
348
349
  end
349
350
 
350
351
  it "should return [] when searching returns an empty array" do
@@ -1,274 +1,658 @@
1
1
  require 'spec_helper'
2
2
  require 'puppet/network/http/connection'
3
+ require 'puppet/network/http/connection_adapter'
3
4
  require 'puppet/test_ca'
4
5
 
5
6
  describe Puppet::Network::HTTP::Connection do
6
- let (:host) { "me.example.com" }
7
- let (:port) { 8140 }
8
- let (:url) { "https://#{host}:#{port}/foo" }
7
+ let(:host) { "me.example.com" }
8
+ let(:port) { 8140 }
9
+ let(:path) { '/foo' }
10
+ let(:url) { "https://#{host}:#{port}#{path}" }
11
+ let(:params) { { 'key' => 'a value' } }
12
+ let(:encoded_url_with_params) { "#{url}?%7B%22key%22:%22a%20value%22%7D" }
9
13
 
10
- subject { Puppet::Network::HTTP::Connection.new(host, port, :verify => Puppet::SSL::Validator.no_validator) }
14
+ shared_examples_for "an HTTP connection" do |klass, legacy_api|
15
+ subject { klass.new(host, port, :verify => Puppet::SSL::Validator.no_validator) }
11
16
 
12
- context "when providing HTTP connections" do
13
- context "when initializing http instances" do
14
- it "should return an http instance created with the passed host and port" do
15
- conn = Puppet::Network::HTTP::Connection.new(host, port, :verify => Puppet::SSL::Validator.no_validator)
17
+ context "when providing HTTP connections" do
18
+ context "when initializing http instances" do
19
+ it "should return an http instance created with the passed host and port" do
20
+ conn = klass.new(host, port, :verify => Puppet::SSL::Validator.no_validator)
16
21
 
17
- expect(conn.address).to eq(host)
18
- expect(conn.port).to eq(port)
22
+ expect(conn.address).to eq(host)
23
+ expect(conn.port).to eq(port)
24
+ end
25
+
26
+ it "should enable ssl on the http instance by default" do
27
+ conn = klass.new(host, port, :verify => Puppet::SSL::Validator.no_validator)
28
+
29
+ expect(conn).to be_use_ssl
30
+ end
31
+
32
+ it "can disable ssl using an option and ignore the verify" do
33
+ conn = klass.new(host, port, :use_ssl => false)
34
+
35
+ expect(conn).to_not be_use_ssl
36
+ end
37
+
38
+ it "can enable ssl using an option" do
39
+ conn = klass.new(host, port, :use_ssl => true, :verify => Puppet::SSL::Validator.no_validator)
40
+
41
+ expect(conn).to be_use_ssl
42
+ end
43
+
44
+ it "ignores the ':verify' option when ssl is disabled" do
45
+ conn = klass.new(host, port, :use_ssl => false, :verify => Puppet::SSL::Validator.no_validator)
46
+
47
+ expect(conn.verifier).to be_nil
48
+ end
49
+
50
+ it "wraps the validator in an adapter" do
51
+ conn = klass.new(host, port, :verify => Puppet::SSL::Validator.no_validator)
52
+
53
+ expect(conn.verifier).to be_a_kind_of(Puppet::SSL::VerifierAdapter)
54
+ end
55
+
56
+ it "should raise Puppet::Error when invalid options are specified" do
57
+ expect { klass.new(host, port, :invalid_option => nil) }.to raise_error(Puppet::Error, 'Unrecognized option(s): :invalid_option')
58
+ end
59
+
60
+ it "accepts a verifier" do
61
+ verifier = Puppet::SSL::Verifier.new(host, double('ssl_context'))
62
+ conn = klass.new(host, port, :use_ssl => true, :verifier => verifier)
63
+
64
+ expect(conn.verifier).to eq(verifier)
65
+ end
66
+
67
+ it "raises if the wrong verifier class is specified" do
68
+ expect {
69
+ klass.new(host, port, :verifier => Puppet::SSL::Validator.default_validator)
70
+ }.to raise_error(ArgumentError,
71
+ "Expected an instance of Puppet::SSL::Verifier but was passed a Puppet::SSL::Validator::DefaultValidator")
72
+ end
19
73
  end
74
+ end
20
75
 
21
- it "should enable ssl on the http instance by default" do
22
- conn = Puppet::Network::HTTP::Connection.new(host, port, :verify => Puppet::SSL::Validator.no_validator)
76
+ context "for streaming GET requests" do
77
+ it 'yields the response' do
78
+ stub_request(:get, url)
23
79
 
24
- expect(conn).to be_use_ssl
80
+ expect { |b|
81
+ subject.request_get('/foo', {}, &b)
82
+ }.to yield_with_args(Net::HTTPResponse)
25
83
  end
26
84
 
27
- it "can disable ssl using an option and ignore the verify" do
28
- conn = Puppet::Network::HTTP::Connection.new(host, port, :use_ssl => false)
85
+ it "stringifies keys and encodes values in the query" do
86
+ stub_request(:get, encoded_url_with_params)
29
87
 
30
- expect(conn).to_not be_use_ssl
88
+ subject.request_get("#{path}?#{params.to_json}") { |_| }
31
89
  end
32
90
 
33
- it "can enable ssl using an option" do
34
- conn = Puppet::Network::HTTP::Connection.new(host, port, :use_ssl => true, :verify => Puppet::SSL::Validator.no_validator)
91
+ it "merges custom headers with default ones" do
92
+ stub_request(:get, url).with(headers: { 'X-Foo' => 'Bar', 'User-Agent' => /./ })
35
93
 
36
- expect(conn).to be_use_ssl
94
+ subject.request_get(path, {'X-Foo' => 'Bar'}) { |_| }
37
95
  end
38
96
 
39
- it "ignores the ':verify' option when ssl is disabled" do
40
- conn = Puppet::Network::HTTP::Connection.new(host, port, :use_ssl => false, :verify => Puppet::SSL::Validator.no_validator)
97
+ it "returns the response" do
98
+ stub_request(:get, url)
41
99
 
42
- expect(conn.verifier).to be_nil
100
+ response = subject.request_get(path) { |_| }
101
+ expect(response).to be_an_instance_of(Net::HTTPOK)
102
+ expect(response.code).to eq("200")
43
103
  end
44
104
 
45
- it "wraps the validator in an adapter" do
46
- conn = Puppet::Network::HTTP::Connection.new(host, port, :verify => Puppet::SSL::Validator.no_validator)
105
+ it "accepts a URL string as the path" do
106
+ url_with_query = "#{url}?foo=bar"
107
+ stub_request(:get, url_with_query)
47
108
 
48
- expect(conn.verifier).to be_a_kind_of(Puppet::SSL::VerifierAdapter)
109
+ response = subject.request_get(url_with_query) { |_| }
110
+ expect(response).to be_an_instance_of(Net::HTTPOK)
49
111
  end
112
+ end
50
113
 
51
- it "should raise Puppet::Error when invalid options are specified" do
52
- expect { Puppet::Network::HTTP::Connection.new(host, port, :invalid_option => nil) }.to raise_error(Puppet::Error, 'Unrecognized option(s): :invalid_option')
114
+ context "for streaming head requests" do
115
+ it 'yields the response when request_head is called' do
116
+ stub_request(:head, url)
117
+
118
+ expect { |b|
119
+ subject.request_head('/foo', {}, &b)
120
+ }.to yield_with_args(Net::HTTPResponse)
53
121
  end
54
122
 
55
- it "accepts a verifier" do
56
- verifier = Puppet::SSL::Verifier.new('fqdn', double('ssl_context'))
57
- conn = Puppet::Network::HTTP::Connection.new(host, port, :use_ssl => true, :verifier => verifier)
123
+ it "stringifies keys and encodes values in the query" do
124
+ stub_request(:head, encoded_url_with_params)
58
125
 
59
- expect(conn.verifier).to eq(verifier)
126
+ subject.request_head("#{path}?#{params.to_json}") { |_| }
60
127
  end
61
128
 
62
- it "raises if the wrong verifier class is specified" do
63
- expect {
64
- Puppet::Network::HTTP::Connection.new(host, port, :verifier => Puppet::SSL::Validator.default_validator)
65
- }.to raise_error(ArgumentError,
66
- "Expected an instance of Puppet::SSL::Verifier but was passed a Puppet::SSL::Validator::DefaultValidator")
129
+ it "merges custom headers with default ones" do
130
+ stub_request(:head, url).with(headers: { 'X-Foo' => 'Bar', 'User-Agent' => /./ })
131
+
132
+ subject.request_head(path, {'X-Foo' => 'Bar'}) { |_| }
67
133
  end
68
- end
69
- end
70
134
 
71
- context "when handling requests" do
72
- it 'yields the response when request_get is called' do
73
- stub_request(:get, url)
135
+ it "returns the response" do
136
+ stub_request(:head, url)
74
137
 
75
- expect { |b|
76
- subject.request_get('/foo', {}, &b)
77
- }.to yield_with_args(Net::HTTPResponse)
78
- end
138
+ response = subject.request_head(path) { |_| }
139
+ expect(response).to be_an_instance_of(Net::HTTPOK)
140
+ expect(response.code).to eq("200")
141
+ end
79
142
 
80
- it 'yields the response when request_head is called' do
81
- stub_request(:head, url)
143
+ it "accepts a URL string as the path" do
144
+ url_with_query = "#{url}?foo=bar"
145
+ stub_request(:head, url_with_query)
82
146
 
83
- expect { |b|
84
- subject.request_head('/foo', {}, &b)
85
- }.to yield_with_args(Net::HTTPResponse)
147
+ response = subject.request_head(url_with_query) { |_| }
148
+ expect(response).to be_an_instance_of(Net::HTTPOK)
149
+ end
86
150
  end
87
151
 
88
- it 'yields the response when request_post is called' do
89
- stub_request(:post, url)
152
+ context "for streaming post requests" do
153
+ it 'yields the response when request_post is called' do
154
+ stub_request(:post, url)
90
155
 
91
- expect { |b|
92
- subject.request_post('/foo', "param: value", &b)
93
- }.to yield_with_args(Net::HTTPResponse)
94
- end
95
- end
156
+ expect { |b|
157
+ subject.request_post('/foo', "param: value", &b)
158
+ }.to yield_with_args(Net::HTTPResponse)
159
+ end
96
160
 
97
- context "when response is a redirect" do
98
- def create_connection(options = {})
99
- options[:use_ssl] = false
100
- options[:verify] = Puppet::SSL::Validator.no_validator
101
- Puppet::Network::HTTP::Connection.new(host, port, options)
102
- end
161
+ it "stringifies keys and encodes values in the query" do
162
+ stub_request(:post, encoded_url_with_params)
103
163
 
104
- def redirect_to(url)
105
- { status: 302, headers: { 'Location' => url } }
106
- end
164
+ subject.request_post("#{path}?#{params.to_json}", "") { |_| }
165
+ end
107
166
 
108
- it "should follow the redirect to the final resource location" do
109
- stub_request(:get, "http://me.example.com:8140/foo").to_return(redirect_to("http://me.example.com:8140/bar"))
110
- stub_request(:get, "http://me.example.com:8140/bar").to_return(status: 200)
167
+ it "merges custom headers with default ones" do
168
+ stub_request(:post, url).with(headers: { 'X-Foo' => 'Bar', 'User-Agent' => /./ })
111
169
 
112
- create_connection.get('/foo')
113
- end
170
+ subject.request_post(path, "", {'X-Foo' => 'Bar'}) { |_| }
171
+ end
114
172
 
115
- def expects_limit_exceeded(conn)
116
- expect {
117
- conn.get('/')
118
- }.to raise_error(Puppet::Network::HTTP::RedirectionLimitExceededException)
119
- end
173
+ it "returns the response" do
174
+ stub_request(:post, url)
175
+
176
+ response = subject.request_post(path, "") { |_| }
177
+ expect(response).to be_an_instance_of(Net::HTTPOK)
178
+ expect(response.code).to eq("200")
179
+ end
120
180
 
121
- it "should not follow any redirects when the limit is 0" do
122
- stub_request(:get, "http://me.example.com:8140/").to_return(redirect_to("http://me.example.com:8140/foo"))
181
+ it "accepts a URL string as the path" do
182
+ url_with_query = "#{url}?foo=bar"
183
+ stub_request(:post, url_with_query)
123
184
 
124
- conn = create_connection(:redirect_limit => 0)
125
- expects_limit_exceeded(conn)
185
+ response = subject.request_post(url_with_query, "") { |_| }
186
+ expect(response).to be_an_instance_of(Net::HTTPOK)
187
+ end
126
188
  end
127
189
 
128
- it "should follow the redirect once" do
129
- stub_request(:get, "http://me.example.com:8140/").to_return(redirect_to("http://me.example.com:8140/foo"))
130
- stub_request(:get, "http://me.example.com:8140/foo").to_return(redirect_to("http://me.example.com:8140/bar"))
190
+ context "for GET requests" do
191
+ it "includes default HTTP headers" do
192
+ stub_request(:get, url).with(headers: {'User-Agent' => /./})
131
193
 
132
- conn = create_connection(:redirect_limit => 1)
133
- expects_limit_exceeded(conn)
134
- end
194
+ subject.get(path)
195
+ end
135
196
 
136
- it "should raise an exception when the redirect limit is exceeded" do
137
- stub_request(:get, "http://me.example.com:8140/").to_return(redirect_to("http://me.example.com:8140/foo"))
138
- stub_request(:get, "http://me.example.com:8140/foo").to_return(redirect_to("http://me.example.com:8140/bar"))
139
- stub_request(:get, "http://me.example.com:8140/bar").to_return(redirect_to("http://me.example.com:8140/baz"))
140
- stub_request(:get, "http://me.example.com:8140/baz").to_return(redirect_to("http://me.example.com:8140/qux"))
197
+ it "stringifies keys and encodes values in the query" do
198
+ stub_request(:get, encoded_url_with_params)
141
199
 
142
- conn = create_connection(:redirect_limit => 3)
143
- expects_limit_exceeded(conn)
144
- end
145
- end
200
+ subject.get("#{path}?#{params.to_json}")
201
+ end
146
202
 
147
- context "when response indicates an overloaded server" do
148
- def retry_after(datetime)
149
- stub_request(:get, url)
150
- .to_return(status: [503, 'Service Unavailable'], headers: {'Retry-After' => datetime}).then
151
- .to_return(status: 200)
152
- end
203
+ it "merges custom headers with default ones" do
204
+ stub_request(:get, url).with(headers: { 'X-Foo' => 'Bar', 'User-Agent' => /./ })
153
205
 
154
- it "should return a 503 response if Retry-After is not set" do
155
- stub_request(:get, url).to_return(status: [503, 'Service Unavailable'])
206
+ subject.get(path, {'X-Foo' => 'Bar'})
207
+ end
156
208
 
157
- result = subject.get('/foo')
158
- expect(result.code).to eq("503")
159
- end
209
+ it "returns the response" do
210
+ stub_request(:get, url)
160
211
 
161
- it "should return a 503 response if Retry-After is not convertible to an Integer or RFC 2822 Date" do
162
- stub_request(:get, url).to_return(status: [503, 'Service Unavailable'], headers: {'Retry-After' => 'foo'})
212
+ response = subject.get(path)
213
+ expect(response).to be_an_instance_of(Net::HTTPOK)
214
+ expect(response.code).to eq("200")
215
+ end
163
216
 
164
- result = subject.get('/foo')
165
- expect(result.code).to eq("503")
166
- end
217
+ it "returns the entire response body" do
218
+ stub_request(:get, url).to_return(body: "abc")
167
219
 
168
- it "should sleep and retry if Retry-After is an Integer" do
169
- retry_after('42')
220
+ response = subject.get(path)
221
+ expect(response.body).to eq("abc")
222
+ end
170
223
 
171
- expect(::Kernel).to receive(:sleep).with(42)
224
+ it "accepts a URL string as the path" do
225
+ url_with_query = "#{url}?foo=bar"
226
+ stub_request(:get, url_with_query)
172
227
 
173
- result = subject.get('/foo')
174
- expect(result.code).to eq("200")
228
+ response = subject.get(url_with_query)
229
+ expect(response).to be_an_instance_of(Net::HTTPOK)
230
+ end
175
231
  end
176
232
 
177
- it "should sleep and retry if Retry-After is an RFC 2822 Date" do
178
- retry_after('Wed, 13 Apr 2005 15:18:05 GMT')
233
+ context "for HEAD requests" do
234
+ it "includes default HTTP headers" do
235
+ stub_request(:head, url).with(headers: {'User-Agent' => /./})
236
+
237
+ subject.head(path)
238
+ end
179
239
 
180
- now = DateTime.new(2005, 4, 13, 8, 17, 5, '-07:00')
181
- allow(DateTime).to receive(:now).and_return(now)
240
+ it "stringifies keys and encodes values in the query" do
241
+ stub_request(:head, encoded_url_with_params)
182
242
 
183
- expect(::Kernel).to receive(:sleep).with(60)
243
+ subject.head("#{path}?#{params.to_json}")
244
+ end
184
245
 
185
- result = subject.get('/foo')
186
- expect(result.code).to eq("200")
187
- end
246
+ it "merges custom headers with default ones" do
247
+ stub_request(:head, url).with(headers: { 'X-Foo' => 'Bar', 'User-Agent' => /./ })
188
248
 
189
- it "should sleep for no more than the Puppet runinterval" do
190
- retry_after('60')
191
- Puppet[:runinterval] = 30
249
+ subject.head(path, {'X-Foo' => 'Bar'})
250
+ end
192
251
 
193
- expect(::Kernel).to receive(:sleep).with(30)
252
+ it "returns the response" do
253
+ stub_request(:head, url)
194
254
 
195
- subject.get('/foo')
255
+ response = subject.head(path)
256
+ expect(response).to be_an_instance_of(Net::HTTPOK)
257
+ expect(response.code).to eq("200")
258
+ end
259
+
260
+ it "accepts a URL string as the path" do
261
+ url_with_query = "#{url}?foo=bar"
262
+ stub_request(:head, url_with_query)
263
+
264
+ response = subject.head(url_with_query)
265
+ expect(response).to be_an_instance_of(Net::HTTPOK)
266
+ end
196
267
  end
197
268
 
198
- it "should sleep for 0 seconds if the RFC 2822 date has past" do
199
- retry_after('Wed, 13 Apr 2005 15:18:05 GMT')
269
+ context "for PUT requests" do
270
+ it "includes default HTTP headers" do
271
+ stub_request(:put, url).with(headers: {'User-Agent' => /./})
200
272
 
201
- expect(::Kernel).to receive(:sleep).with(0)
273
+ subject.put(path, "", {'Content-Type' => 'text/plain'})
274
+ end
202
275
 
203
- subject.get('/foo')
204
- end
205
- end
276
+ it "stringifies keys and encodes values in the query" do
277
+ stub_request(:put, encoded_url_with_params)
206
278
 
207
- context "basic auth" do
208
- let(:auth) { { :user => 'user', :password => 'password' } }
209
- let(:creds) { [ 'user', 'password'] }
279
+ subject.put("#{path}?#{params.to_json}", "")
280
+ end
281
+
282
+ it "includes custom headers" do
283
+ stub_request(:put, url).with(headers: { 'X-Foo' => 'Bar' })
284
+
285
+ subject.put(path, "", {'X-Foo' => 'Bar', 'Content-Type' => 'text/plain'})
286
+ end
287
+
288
+ it "returns the response" do
289
+ stub_request(:put, url)
290
+
291
+ response = subject.put(path, "", {'Content-Type' => 'text/plain'})
292
+ expect(response).to be_an_instance_of(Net::HTTPOK)
293
+ expect(response.code).to eq("200")
294
+ end
295
+
296
+ it "sets content-type for the body" do
297
+ stub_request(:put, url).with(headers: {"Content-Type" => "text/plain"})
298
+
299
+ subject.put(path, "hello", {'Content-Type' => 'text/plain'})
300
+ end
301
+
302
+ it 'sends an empty body' do
303
+ stub_request(:put, url).with(body: '')
210
304
 
211
- it "is allowed in get requests" do
212
- stub_request(:get, url).with(basic_auth: creds)
305
+ subject.put(path, nil)
306
+ end
213
307
 
214
- subject.get('/foo', nil, :basic_auth => auth)
308
+ it 'defaults content-type to application/x-www-form-urlencoded' do
309
+ skip("Net::HTTP sends a default content-type header, but it's not visible to webmock") if legacy_api
310
+
311
+ stub_request(:put, url).with(headers: {'Content-Type' => 'application/x-www-form-urlencoded'})
312
+
313
+ subject.put(path, '')
314
+ end
315
+
316
+ it "accepts a URL string as the path" do
317
+ url_with_query = "#{url}?foo=bar"
318
+ stub_request(:put, url_with_query)
319
+
320
+ response = subject.put(url_with_query, '')
321
+ expect(response).to be_an_instance_of(Net::HTTPOK)
322
+ end
215
323
  end
216
324
 
217
- it "is allowed in post requests" do
218
- stub_request(:post, url).with(basic_auth: creds)
325
+ context "for POST requests" do
326
+ it "includes default HTTP headers" do
327
+ stub_request(:post, url).with(headers: {'User-Agent' => /./})
328
+
329
+ subject.post(path, "", {'Content-Type' => 'text/plain'})
330
+ end
331
+
332
+ it "stringifies keys and encodes values in the query" do
333
+ stub_request(:post, encoded_url_with_params)
334
+
335
+ subject.post("#{path}?#{params.to_json}", "", {'Content-Type' => 'text/plain'})
336
+ end
337
+
338
+ it "includes custom headers" do
339
+ stub_request(:post, url).with(headers: { 'X-Foo' => 'Bar' })
340
+
341
+ subject.post(path, "", {'X-Foo' => 'Bar', 'Content-Type' => 'text/plain'})
342
+ end
343
+
344
+ it "returns the response" do
345
+ stub_request(:post, url)
346
+
347
+ response = subject.post(path, "", {'Content-Type' => 'text/plain'})
348
+ expect(response).to be_an_instance_of(Net::HTTPOK)
349
+ expect(response.code).to eq("200")
350
+ end
351
+
352
+ it "sets content-type for the body" do
353
+ stub_request(:post, url).with(headers: {"Content-Type" => "text/plain"})
354
+
355
+ subject.post(path, "hello", {'Content-Type' => 'text/plain'})
356
+ end
357
+
358
+ it 'sends an empty body' do
359
+ stub_request(:post, url).with(body: '')
360
+
361
+ subject.post(path, nil)
362
+ end
363
+
364
+ it 'defaults content-type to application/x-www-form-urlencoded' do
365
+ skip("Net::HTTP sends a default content-type header, but it's not visible to webmock") if legacy_api
219
366
 
220
- subject.post('/foo', 'data', nil, :basic_auth => auth)
367
+ stub_request(:post, url).with(headers: {'Content-Type' => 'application/x-www-form-urlencoded'})
368
+
369
+ subject.post(path, "")
370
+ end
371
+
372
+ it "accepts a URL string as the path" do
373
+ url_with_query = "#{url}?foo=bar"
374
+ stub_request(:post, url_with_query)
375
+
376
+ response = subject.post(url_with_query, '')
377
+ expect(response).to be_an_instance_of(Net::HTTPOK)
378
+ end
221
379
  end
222
380
 
223
- it "is allowed in head requests" do
224
- stub_request(:head, url).with(basic_auth: creds)
381
+ context "for DELETE requests" do
382
+ it "includes default HTTP headers" do
383
+ stub_request(:delete, url).with(headers: {'User-Agent' => /./})
384
+
385
+ subject.delete(path)
386
+ end
387
+
388
+ it "merges custom headers with default ones" do
389
+ stub_request(:delete, url).with(headers: { 'X-Foo' => 'Bar', 'User-Agent' => /./ })
390
+
391
+ subject.delete(path, {'X-Foo' => 'Bar'})
392
+ end
393
+
394
+ it "stringifies keys and encodes values in the query" do
395
+ stub_request(:delete, encoded_url_with_params)
396
+
397
+ subject.delete("#{path}?#{params.to_json}")
398
+ end
225
399
 
226
- subject.head('/foo', nil, :basic_auth => auth)
400
+ it "returns the response" do
401
+ stub_request(:delete, url)
402
+
403
+ response = subject.delete(path)
404
+ expect(response).to be_an_instance_of(Net::HTTPOK)
405
+ expect(response.code).to eq("200")
406
+ end
407
+
408
+ it "returns the entire response body" do
409
+ stub_request(:delete, url).to_return(body: "abc")
410
+
411
+ expect(subject.delete(path).body).to eq("abc")
412
+ end
413
+
414
+ it "accepts a URL string as the path" do
415
+ url_with_query = "#{url}?foo=bar"
416
+ stub_request(:delete, url_with_query)
417
+
418
+ response = subject.delete(url_with_query)
419
+ expect(response).to be_an_instance_of(Net::HTTPOK)
420
+ end
227
421
  end
228
422
 
229
- it "is allowed in delete requests" do
230
- stub_request(:delete, url).with(basic_auth: creds)
423
+ context "when response is a redirect" do
424
+ subject { klass }
425
+
426
+ def create_connection(options = {})
427
+ options[:use_ssl] = false
428
+ options[:verify] = Puppet::SSL::Validator.no_validator
429
+ subject.new(host, port, options)
430
+ end
431
+
432
+ def redirect_to(url)
433
+ { status: 302, headers: { 'Location' => url } }
434
+ end
231
435
 
232
- subject.delete('/foo', nil, :basic_auth => auth)
436
+ it "should follow the redirect to the final resource location" do
437
+ stub_request(:get, "http://me.example.com:8140/foo").to_return(redirect_to("http://me.example.com:8140/bar"))
438
+ stub_request(:get, "http://me.example.com:8140/bar").to_return(status: 200)
439
+
440
+ create_connection.get('/foo')
441
+ end
442
+
443
+ def expects_limit_exceeded(conn)
444
+ expect {
445
+ conn.get('/')
446
+ }.to raise_error(Puppet::Network::HTTP::RedirectionLimitExceededException)
447
+ end
448
+
449
+ it "should not follow any redirects when the limit is 0" do
450
+ stub_request(:get, "http://me.example.com:8140/").to_return(redirect_to("http://me.example.com:8140/foo"))
451
+
452
+ conn = create_connection(:redirect_limit => 0)
453
+ expects_limit_exceeded(conn)
454
+ end
455
+
456
+ it "should follow the redirect once" do
457
+ stub_request(:get, "http://me.example.com:8140/").to_return(redirect_to("http://me.example.com:8140/foo"))
458
+ stub_request(:get, "http://me.example.com:8140/foo").to_return(redirect_to("http://me.example.com:8140/bar"))
459
+
460
+ conn = create_connection(:redirect_limit => 1)
461
+ expects_limit_exceeded(conn)
462
+ end
463
+
464
+ it "should raise an exception when the redirect limit is exceeded" do
465
+ stub_request(:get, "http://me.example.com:8140/").to_return(redirect_to("http://me.example.com:8140/foo"))
466
+ stub_request(:get, "http://me.example.com:8140/foo").to_return(redirect_to("http://me.example.com:8140/bar"))
467
+ stub_request(:get, "http://me.example.com:8140/bar").to_return(redirect_to("http://me.example.com:8140/baz"))
468
+ stub_request(:get, "http://me.example.com:8140/baz").to_return(redirect_to("http://me.example.com:8140/qux"))
469
+
470
+ conn = create_connection(:redirect_limit => 3)
471
+ expects_limit_exceeded(conn)
472
+ end
473
+
474
+ it 'raises an exception when the location header is missing' do
475
+ stub_request(:get, "http://me.example.com:8140/").to_return(status: 302)
476
+
477
+ if legacy_api
478
+ expect {
479
+ create_connection.get('/')
480
+ }.to raise_error(URI::InvalidURIError, /bad URI/)
481
+ else
482
+ expect {
483
+ create_connection.get('/')
484
+ }.to raise_error(Puppet::HTTP::ProtocolError, /Location response header is missing/)
485
+ end
486
+ end
233
487
  end
234
488
 
235
- it "is allowed in put requests" do
236
- stub_request(:put, url).with(basic_auth: creds)
489
+ context "when response indicates an overloaded server" do
490
+ def retry_after(datetime)
491
+ stub_request(:get, url)
492
+ .to_return(status: [503, 'Service Unavailable'], headers: {'Retry-After' => datetime}).then
493
+ .to_return(status: 200)
494
+ end
495
+
496
+ it "should return a 503 response if Retry-After is not set" do
497
+ stub_request(:get, url).to_return(status: [503, 'Service Unavailable'])
498
+
499
+ result = subject.get('/foo')
500
+ expect(result.code).to eq("503")
501
+ end
502
+
503
+ it "should return a 503 response if Retry-After is not convertible to an Integer or RFC 2822 Date" do
504
+ retry_after('foo')
505
+
506
+ if legacy_api
507
+ result = subject.get('/foo')
508
+ expect(result.code).to eq("503")
509
+ else
510
+ expect {
511
+ subject.get('/foo')
512
+ }.to raise_error(Puppet::HTTP::ProtocolError, /Failed to parse Retry-After header 'foo'/)
513
+ end
514
+ end
515
+
516
+ it "should close the connection before sleeping" do
517
+ retry_after('42')
518
+
519
+ http1 = Net::HTTP.new(host, port)
520
+ http1.use_ssl = true
521
+ allow(http1).to receive(:started?).and_return(true)
237
522
 
238
- subject.put('/foo', 'data', nil, :basic_auth => auth)
523
+ http2 = Net::HTTP.new(host, port)
524
+ http2.use_ssl = true
525
+ allow(http1).to receive(:started?).and_return(true)
526
+
527
+ # The "with_connection" method is required to yield started connections
528
+ pool = if legacy_api
529
+ Puppet.lookup(:http_pool)
530
+ else
531
+ Puppet.runtime[:http].pool
532
+ end
533
+
534
+ allow(pool).to receive(:with_connection).and_yield(http1).and_yield(http2)
535
+
536
+ expect(http1).to receive(:finish).ordered
537
+ expect(::Kernel).to receive(:sleep).with(42).ordered
538
+
539
+ subject.get('/foo')
540
+ end
541
+
542
+ it "should sleep and retry if Retry-After is an Integer" do
543
+ retry_after('42')
544
+
545
+ expect(::Kernel).to receive(:sleep).with(42)
546
+
547
+ result = subject.get('/foo')
548
+ expect(result.code).to eq("200")
549
+ end
550
+
551
+ it "should sleep and retry if Retry-After is an RFC 2822 Date" do
552
+ retry_after('Wed, 13 Apr 2005 15:18:05 GMT')
553
+
554
+ now = DateTime.new(2005, 4, 13, 8, 17, 5, '-07:00')
555
+ allow(DateTime).to receive(:now).and_return(now)
556
+
557
+ expect(::Kernel).to receive(:sleep).with(60)
558
+
559
+ result = subject.get('/foo')
560
+ expect(result.code).to eq("200")
561
+ end
562
+
563
+ it "should sleep for no more than the Puppet runinterval" do
564
+ retry_after('60')
565
+
566
+ Puppet[:runinterval] = 30
567
+
568
+ expect(::Kernel).to receive(:sleep).with(30)
569
+
570
+ subject.get('/foo')
571
+ end
572
+
573
+ it "should sleep for 0 seconds if the RFC 2822 date has past" do
574
+ retry_after('Wed, 13 Apr 2005 15:18:05 GMT')
575
+
576
+ expect(::Kernel).to receive(:sleep).with(0)
577
+
578
+ subject.get('/foo')
579
+ end
239
580
  end
240
- end
241
581
 
242
- it "sets HTTP User-Agent header" do
243
- puppet_ua = "Puppet/#{Puppet.version} Ruby/#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} (#{RUBY_PLATFORM})"
244
- stub_request(:get, url).with(headers: { 'User-Agent' => puppet_ua })
582
+ context "basic auth" do
583
+ let(:auth) { { :user => 'user', :password => 'password' } }
584
+ let(:creds) { [ 'user', 'password'] }
245
585
 
246
- subject.get('/foo')
247
- end
586
+ it "is allowed in get requests" do
587
+ stub_request(:get, url).with(basic_auth: creds)
248
588
 
249
- describe 'connection request errors' do
250
- it "logs and raises generic http errors" do
251
- generic_error = Net::HTTPError.new('generic error', double("response"))
252
- stub_request(:get, url).to_raise(generic_error)
589
+ subject.get('/foo', nil, :basic_auth => auth)
590
+ end
591
+
592
+ it "is allowed in post requests" do
593
+ stub_request(:post, url).with(basic_auth: creds)
594
+
595
+ subject.post('/foo', 'data', nil, :basic_auth => auth)
596
+ end
597
+
598
+ it "is allowed in head requests" do
599
+ stub_request(:head, url).with(basic_auth: creds)
600
+
601
+ subject.head('/foo', nil, :basic_auth => auth)
602
+ end
603
+
604
+ it "is allowed in delete requests" do
605
+ stub_request(:delete, url).with(basic_auth: creds)
606
+
607
+ subject.delete('/foo', nil, :basic_auth => auth)
608
+ end
609
+
610
+ it "is allowed in put requests" do
611
+ stub_request(:put, url).with(basic_auth: creds)
253
612
 
254
- expect(Puppet).to receive(:log_exception).with(anything, /^.*failed: generic error$/)
255
- expect { subject.get('/foo') }.to raise_error(generic_error)
613
+ subject.put('/foo', 'data', nil, :basic_auth => auth)
614
+ end
256
615
  end
257
616
 
258
- it "logs and raises timeout errors" do
259
- timeout_error = Timeout::Error.new
260
- stub_request(:get, url).to_raise(timeout_error)
617
+ it "sets HTTP User-Agent header" do
618
+ puppet_ua = "Puppet/#{Puppet.version} Ruby/#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} (#{RUBY_PLATFORM})"
619
+ stub_request(:get, url).with(headers: { 'User-Agent' => puppet_ua })
261
620
 
262
- expect(Puppet).to receive(:log_exception).with(anything, /^.*timed out after .* seconds$/)
263
- expect { subject.get('/foo') }.to raise_error(timeout_error)
621
+ subject.get('/foo')
264
622
  end
265
623
 
266
- it "logs and raises eof errors" do
267
- eof_error = EOFError
268
- stub_request(:get, url).to_raise(eof_error)
624
+ describe 'connection request errors' do
625
+ it "logs and raises generic http errors" do
626
+ generic_error = Net::HTTPError.new('generic error', double("response"))
627
+ stub_request(:get, url).to_raise(generic_error)
628
+
629
+ expect(Puppet).to receive(:log_exception).with(anything, /^.*failed.*: generic error$/)
630
+ expect { subject.get('/foo') }.to raise_error(generic_error)
631
+ end
632
+
633
+ it "logs and raises timeout errors" do
634
+ timeout_error = Net::OpenTimeout.new
635
+ stub_request(:get, url).to_raise(timeout_error)
636
+
637
+ expect(Puppet).to receive(:log_exception).with(anything, /^.*timed out .*after .* seconds/)
638
+ expect { subject.get('/foo') }.to raise_error(timeout_error)
639
+ end
640
+
641
+ it "logs and raises eof errors" do
642
+ eof_error = EOFError
643
+ stub_request(:get, url).to_raise(eof_error)
269
644
 
270
- expect(Puppet).to receive(:log_exception).with(anything, /^.*interrupted after .* seconds$/)
271
- expect { subject.get('/foo') }.to raise_error(eof_error)
645
+ expect(Puppet).to receive(:log_exception).with(anything, /^.*interrupted after .* seconds$/)
646
+ expect { subject.get('/foo') }.to raise_error(eof_error)
647
+ end
272
648
  end
273
649
  end
650
+
651
+ describe Puppet::Network::HTTP::Connection do
652
+ it_behaves_like "an HTTP connection", described_class, true
653
+ end
654
+
655
+ describe Puppet::Network::HTTP::ConnectionAdapter do
656
+ it_behaves_like "an HTTP connection", described_class, false
657
+ end
274
658
  end