puppet 6.15.0-x86-mingw32 → 6.19.1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (418) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +2 -7
  3. data/Gemfile +4 -2
  4. data/Gemfile.lock +29 -27
  5. data/README.md +3 -4
  6. data/Rakefile +4 -12
  7. data/lib/puppet.rb +32 -8
  8. data/lib/puppet/agent.rb +18 -4
  9. data/lib/puppet/agent/locker.rb +0 -7
  10. data/lib/puppet/application/agent.rb +23 -8
  11. data/lib/puppet/application/apply.rb +18 -20
  12. data/lib/puppet/application/device.rb +1 -1
  13. data/lib/puppet/application/doc.rb +1 -1
  14. data/lib/puppet/application/lookup.rb +16 -4
  15. data/lib/puppet/application/plugin.rb +1 -0
  16. data/lib/puppet/application/ssl.rb +1 -1
  17. data/lib/puppet/configurer.rb +61 -21
  18. data/lib/puppet/configurer/downloader.rb +31 -10
  19. data/lib/puppet/confine.rb +2 -2
  20. data/lib/puppet/confine/any.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 +119 -39
  24. data/lib/puppet/environments.rb +51 -10
  25. data/lib/puppet/face/catalog.rb +1 -1
  26. data/lib/puppet/face/config.rb +46 -16
  27. data/lib/puppet/face/facts.rb +1 -1
  28. data/lib/puppet/face/help.rb +29 -3
  29. data/lib/puppet/face/module/search.rb +5 -0
  30. data/lib/puppet/face/node.rb +3 -3
  31. data/lib/puppet/face/node/clean.rb +2 -2
  32. data/lib/puppet/face/plugin.rb +1 -1
  33. data/lib/puppet/face/status.rb +1 -1
  34. data/lib/puppet/feature/base.rb +1 -1
  35. data/lib/puppet/file_bucket/dipper.rb +1 -1
  36. data/lib/puppet/file_serving/http_metadata.rb +14 -2
  37. data/lib/puppet/file_serving/metadata.rb +4 -1
  38. data/lib/puppet/file_serving/mount/locales.rb +1 -2
  39. data/lib/puppet/file_serving/mount/pluginfacts.rb +1 -2
  40. data/lib/puppet/file_serving/mount/plugins.rb +1 -2
  41. data/lib/puppet/file_serving/terminus_selector.rb +7 -8
  42. data/lib/puppet/file_system/file_impl.rb +4 -4
  43. data/lib/puppet/file_system/uniquefile.rb +12 -16
  44. data/lib/puppet/forge.rb +1 -1
  45. data/lib/puppet/forge/cache.rb +1 -1
  46. data/lib/puppet/forge/repository.rb +4 -7
  47. data/lib/puppet/functions/filter.rb +1 -0
  48. data/lib/puppet/functions/lstrip.rb +4 -4
  49. data/lib/puppet/functions/new.rb +8 -3
  50. data/lib/puppet/functions/reverse_each.rb +1 -1
  51. data/lib/puppet/functions/rstrip.rb +4 -4
  52. data/lib/puppet/functions/step.rb +1 -1
  53. data/lib/puppet/functions/strip.rb +4 -4
  54. data/lib/puppet/gettext/config.rb +5 -5
  55. data/lib/puppet/gettext/module_translations.rb +4 -4
  56. data/lib/puppet/http.rb +1 -0
  57. data/lib/puppet/http/client.rb +28 -12
  58. data/lib/puppet/http/external_client.rb +0 -6
  59. data/lib/puppet/http/redirector.rb +9 -7
  60. data/lib/puppet/http/resolver.rb +5 -8
  61. data/lib/puppet/http/resolver/server_list.rb +18 -36
  62. data/lib/puppet/http/resolver/settings.rb +4 -4
  63. data/lib/puppet/http/resolver/srv.rb +5 -5
  64. data/lib/puppet/http/response.rb +19 -0
  65. data/lib/puppet/http/service.rb +3 -1
  66. data/lib/puppet/http/service/compiler.rb +1 -1
  67. data/lib/puppet/http/service/file_server.rb +1 -1
  68. data/lib/puppet/http/service/puppetserver.rb +39 -0
  69. data/lib/puppet/http/session.rb +5 -4
  70. data/lib/puppet/indirector.rb +1 -1
  71. data/lib/puppet/indirector/catalog/compiler.rb +1 -1
  72. data/lib/puppet/indirector/exec.rb +1 -1
  73. data/lib/puppet/indirector/facts/facter.rb +3 -3
  74. data/lib/puppet/indirector/facts/yaml.rb +1 -1
  75. data/lib/puppet/indirector/file_content/http.rb +5 -0
  76. data/lib/puppet/indirector/file_content/rest.rb +1 -1
  77. data/lib/puppet/indirector/file_metadata/http.rb +28 -8
  78. data/lib/puppet/indirector/file_metadata/rest.rb +2 -2
  79. data/lib/puppet/indirector/hiera.rb +4 -0
  80. data/lib/puppet/indirector/indirection.rb +1 -1
  81. data/lib/puppet/indirector/json.rb +1 -1
  82. data/lib/puppet/indirector/msgpack.rb +1 -1
  83. data/lib/puppet/indirector/report/processor.rb +2 -2
  84. data/lib/puppet/indirector/request.rb +5 -5
  85. data/lib/puppet/indirector/rest.rb +7 -1
  86. data/lib/puppet/indirector/yaml.rb +1 -1
  87. data/lib/puppet/module.rb +1 -2
  88. data/lib/puppet/network/format_support.rb +2 -2
  89. data/lib/puppet/network/http/api/indirected_routes.rb +1 -1
  90. data/lib/puppet/network/http/api/master/v3/environment.rb +3 -0
  91. data/lib/puppet/network/http/api/master/v3/environments.rb +0 -1
  92. data/lib/puppet/network/http/compression.rb +7 -0
  93. data/lib/puppet/network/http/connection.rb +2 -0
  94. data/lib/puppet/network/http/connection_adapter.rb +184 -0
  95. data/lib/puppet/network/http/nocache_pool.rb +1 -0
  96. data/lib/puppet/network/http/route.rb +2 -2
  97. data/lib/puppet/network/http_pool.rb +2 -2
  98. data/lib/puppet/node/environment.rb +12 -5
  99. data/lib/puppet/node/facts.rb +17 -0
  100. data/lib/puppet/pal/catalog_compiler.rb +5 -0
  101. data/lib/puppet/pal/pal_impl.rb +31 -4
  102. data/lib/puppet/parameter.rb +1 -1
  103. data/lib/puppet/parser/ast/leaf.rb +5 -5
  104. data/lib/puppet/parser/ast/pops_bridge.rb +0 -4
  105. data/lib/puppet/parser/compiler.rb +29 -26
  106. data/lib/puppet/parser/compiler/catalog_validator/env_relationship_validator.rb +2 -0
  107. data/lib/puppet/parser/compiler/catalog_validator/site_validator.rb +2 -0
  108. data/lib/puppet/parser/environment_compiler.rb +4 -1
  109. data/lib/puppet/parser/functions.rb +21 -17
  110. data/lib/puppet/parser/functions/create_resources.rb +11 -7
  111. data/lib/puppet/parser/functions/filter.rb +1 -0
  112. data/lib/puppet/parser/resource.rb +3 -2
  113. data/lib/puppet/parser/resource/param.rb +6 -0
  114. data/lib/puppet/parser/type_loader.rb +2 -2
  115. data/lib/puppet/pops/adaptable.rb +7 -13
  116. data/lib/puppet/pops/adapters.rb +8 -4
  117. data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +1 -3
  118. data/lib/puppet/pops/evaluator/evaluator_impl.rb +5 -5
  119. data/lib/puppet/pops/evaluator/runtime3_converter.rb +2 -2
  120. data/lib/puppet/pops/issues.rb +5 -0
  121. data/lib/puppet/pops/loader/runtime3_type_loader.rb +4 -2
  122. data/lib/puppet/pops/loaders.rb +18 -11
  123. data/lib/puppet/pops/lookup/context.rb +1 -1
  124. data/lib/puppet/pops/lookup/hiera_config.rb +14 -1
  125. data/lib/puppet/pops/resource/resource_type_impl.rb +2 -0
  126. data/lib/puppet/pops/types/iterable.rb +34 -8
  127. data/lib/puppet/pops/types/p_meta_type.rb +1 -1
  128. data/lib/puppet/pops/types/p_type_set_type.rb +4 -0
  129. data/lib/puppet/pops/validation/checker4_0.rb +29 -15
  130. data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -0
  131. data/lib/puppet/provider/file/windows.rb +1 -1
  132. data/lib/puppet/provider/package/aix.rb +17 -2
  133. data/lib/puppet/provider/package/apt.rb +38 -1
  134. data/lib/puppet/provider/package/aptitude.rb +1 -1
  135. data/lib/puppet/provider/package/dnfmodule.rb +24 -4
  136. data/lib/puppet/provider/package/dpkg.rb +1 -1
  137. data/lib/puppet/provider/package/gem.rb +4 -2
  138. data/lib/puppet/provider/package/pip.rb +60 -37
  139. data/lib/puppet/provider/package/pip2.rb +17 -0
  140. data/lib/puppet/provider/package/portage.rb +2 -2
  141. data/lib/puppet/provider/package/puppet_gem.rb +5 -0
  142. data/lib/puppet/provider/package/puppetserver_gem.rb +180 -0
  143. data/lib/puppet/provider/package/yum.rb +9 -1
  144. data/lib/puppet/provider/package/zypper.rb +62 -1
  145. data/lib/puppet/provider/service/systemd.rb +21 -4
  146. data/lib/puppet/provider/service/windows.rb +23 -7
  147. data/lib/puppet/provider/user/aix.rb +1 -1
  148. data/lib/puppet/provider/user/user_role_add.rb +1 -1
  149. data/lib/puppet/provider/user/useradd.rb +16 -5
  150. data/lib/puppet/provider/user/windows_adsi.rb +18 -1
  151. data/lib/puppet/reports/http.rb +7 -3
  152. data/lib/puppet/resource.rb +2 -1
  153. data/lib/puppet/resource/type.rb +10 -1
  154. data/lib/puppet/rest/route.rb +2 -2
  155. data/lib/puppet/runtime.rb +25 -2
  156. data/lib/puppet/settings.rb +43 -6
  157. data/lib/puppet/ssl/ssl_context.rb +2 -2
  158. data/lib/puppet/ssl/ssl_provider.rb +20 -1
  159. data/lib/puppet/ssl/state_machine.rb +33 -8
  160. data/lib/puppet/ssl/validator/default_validator.rb +1 -1
  161. data/lib/puppet/ssl/verifier_adapter.rb +9 -1
  162. data/lib/puppet/test/test_helper.rb +19 -14
  163. data/lib/puppet/transaction.rb +2 -2
  164. data/lib/puppet/transaction/persistence.rb +1 -1
  165. data/lib/puppet/transaction/report.rb +12 -8
  166. data/lib/puppet/trusted_external.rb +29 -1
  167. data/lib/puppet/type.rb +15 -7
  168. data/lib/puppet/type/file.rb +40 -15
  169. data/lib/puppet/type/file/checksum.rb +4 -4
  170. data/lib/puppet/type/file/source.rb +33 -13
  171. data/lib/puppet/type/filebucket.rb +1 -1
  172. data/lib/puppet/type/notify.rb +2 -2
  173. data/lib/puppet/type/package.rb +16 -1
  174. data/lib/puppet/type/service.rb +59 -8
  175. data/lib/puppet/type/user.rb +19 -10
  176. data/lib/puppet/util.rb +41 -3
  177. data/lib/puppet/util/autoload.rb +10 -25
  178. data/lib/puppet/util/character_encoding.rb +9 -5
  179. data/lib/puppet/util/checksums.rb +19 -4
  180. data/lib/puppet/util/connection.rb +8 -8
  181. data/lib/puppet/util/execution.rb +2 -2
  182. data/lib/puppet/util/fileparsing.rb +2 -2
  183. data/lib/puppet/util/log/destinations.rb +1 -10
  184. data/lib/puppet/util/package/version/range.rb +4 -1
  185. data/lib/puppet/util/package/version/range/eq.rb +14 -0
  186. data/lib/puppet/util/provider_features.rb +1 -1
  187. data/lib/puppet/util/reference.rb +1 -1
  188. data/lib/puppet/util/run_mode.rb +5 -1
  189. data/lib/puppet/util/windows.rb +1 -0
  190. data/lib/puppet/util/windows/api_types.rb +60 -33
  191. data/lib/puppet/util/windows/eventlog.rb +1 -6
  192. data/lib/puppet/util/windows/monkey_patches/dir.rb +40 -0
  193. data/lib/puppet/util/windows/principal.rb +8 -6
  194. data/lib/puppet/util/windows/registry.rb +11 -11
  195. data/lib/puppet/util/windows/security.rb +4 -4
  196. data/lib/puppet/util/windows/service.rb +43 -26
  197. data/lib/puppet/util/windows/user.rb +242 -8
  198. data/lib/puppet/version.rb +1 -1
  199. data/locales/puppet.pot +541 -427
  200. data/man/man5/puppet.conf.5 +84 -19
  201. data/man/man8/puppet-agent.8 +7 -4
  202. data/man/man8/puppet-apply.8 +1 -1
  203. data/man/man8/puppet-catalog.8 +1 -1
  204. data/man/man8/puppet-config.8 +6 -6
  205. data/man/man8/puppet-describe.8 +1 -1
  206. data/man/man8/puppet-device.8 +1 -1
  207. data/man/man8/puppet-doc.8 +1 -1
  208. data/man/man8/puppet-epp.8 +1 -1
  209. data/man/man8/puppet-facts.8 +1 -1
  210. data/man/man8/puppet-filebucket.8 +1 -1
  211. data/man/man8/puppet-generate.8 +1 -1
  212. data/man/man8/puppet-help.8 +6 -3
  213. data/man/man8/puppet-key.8 +1 -1
  214. data/man/man8/puppet-lookup.8 +2 -2
  215. data/man/man8/puppet-man.8 +1 -1
  216. data/man/man8/puppet-module.8 +4 -1
  217. data/man/man8/puppet-node.8 +4 -4
  218. data/man/man8/puppet-parser.8 +1 -1
  219. data/man/man8/puppet-plugin.8 +1 -1
  220. data/man/man8/puppet-report.8 +1 -1
  221. data/man/man8/puppet-resource.8 +1 -1
  222. data/man/man8/puppet-script.8 +1 -1
  223. data/man/man8/puppet-ssl.8 +1 -1
  224. data/man/man8/puppet-status.8 +2 -2
  225. data/man/man8/puppet.8 +2 -2
  226. data/spec/fixtures/integration/application/apply/environments/spec/modules/amod/lib/puppet/provider/applytest/applytest.rb +2 -0
  227. data/spec/fixtures/integration/application/apply/environments/spec/modules/amod/lib/puppet/type/applytest.rb +25 -0
  228. data/spec/fixtures/unit/forge/bacula-releases.json +128 -0
  229. data/spec/fixtures/unit/forge/bacula.tar.gz +0 -0
  230. data/spec/fixtures/unit/provider/package/dnfmodule/{dnf-module-list-enabled.txt → dnf-module-list.txt} +6 -0
  231. data/spec/fixtures/unit/provider/package/puppetserver_gem/gem-list-local-packages +30 -0
  232. data/spec/fixtures/unit/provider/package/zypper/zypper-search-uninstalled.out +13 -0
  233. data/spec/integration/application/agent_spec.rb +202 -52
  234. data/spec/integration/application/apply_spec.rb +149 -149
  235. data/spec/integration/application/config_spec.rb +74 -0
  236. data/spec/integration/application/doc_spec.rb +16 -6
  237. data/spec/integration/application/filebucket_spec.rb +70 -21
  238. data/spec/integration/application/help_spec.rb +42 -0
  239. data/spec/integration/application/lookup_spec.rb +13 -0
  240. data/spec/integration/application/module_spec.rb +68 -0
  241. data/spec/integration/application/plugin_spec.rb +75 -2
  242. data/spec/integration/configurer_spec.rb +14 -0
  243. data/spec/integration/data_binding_spec.rb +82 -0
  244. data/spec/integration/defaults_spec.rb +27 -3
  245. data/spec/integration/directory_environments_spec.rb +17 -17
  246. data/spec/integration/http/client_spec.rb +6 -1
  247. data/spec/integration/indirector/facts/facter_spec.rb +8 -6
  248. data/spec/integration/network/http_pool_spec.rb +73 -0
  249. data/spec/integration/node/environment_spec.rb +1 -1
  250. data/spec/integration/parser/compiler_spec.rb +11 -0
  251. data/spec/integration/type/file_spec.rb +1 -1
  252. data/spec/integration/util/execution_spec.rb +22 -0
  253. data/spec/integration/util/windows/adsi_spec.rb +7 -2
  254. data/spec/integration/util/windows/monkey_patches/dir_spec.rb +11 -0
  255. data/spec/integration/util/windows/process_spec.rb +26 -32
  256. data/spec/integration/util/windows/registry_spec.rb +7 -7
  257. data/spec/integration/util/windows/user_spec.rb +47 -5
  258. data/spec/integration/util_spec.rb +7 -33
  259. data/spec/lib/puppet_spec/https.rb +6 -0
  260. data/spec/lib/puppet_spec/matchers.rb +0 -80
  261. data/spec/lib/puppet_spec/puppetserver.rb +8 -0
  262. data/spec/shared_contexts/types_setup.rb +2 -0
  263. data/spec/unit/agent_spec.rb +47 -1
  264. data/spec/unit/application/agent_spec.rb +7 -8
  265. data/spec/unit/application/doc_spec.rb +2 -2
  266. data/spec/unit/application/face_base_spec.rb +6 -4
  267. data/spec/unit/application/facts_spec.rb +41 -10
  268. data/spec/unit/application/man_spec.rb +52 -0
  269. data/spec/unit/application/resource_spec.rb +3 -1
  270. data/spec/unit/application/ssl_spec.rb +15 -2
  271. data/spec/unit/application_spec.rb +9 -4
  272. data/spec/unit/configurer/downloader_spec.rb +10 -0
  273. data/spec/unit/configurer/fact_handler_spec.rb +4 -4
  274. data/spec/unit/configurer_spec.rb +86 -37
  275. data/spec/unit/confine_spec.rb +2 -1
  276. data/spec/unit/context/trusted_information_spec.rb +25 -2
  277. data/spec/unit/daemon_spec.rb +5 -64
  278. data/spec/unit/environments_spec.rb +99 -32
  279. data/spec/unit/face/config_spec.rb +59 -1
  280. data/spec/unit/face/module/search_spec.rb +17 -0
  281. data/spec/unit/face/node_spec.rb +2 -2
  282. data/spec/unit/file_serving/http_metadata_spec.rb +37 -14
  283. data/spec/unit/file_serving/mount/locales_spec.rb +2 -2
  284. data/spec/unit/file_serving/mount/pluginfacts_spec.rb +2 -2
  285. data/spec/unit/file_serving/mount/plugins_spec.rb +2 -2
  286. data/spec/unit/file_serving/terminus_selector_spec.rb +45 -26
  287. data/spec/unit/file_system/uniquefile_spec.rb +29 -0
  288. data/spec/unit/file_system_spec.rb +1 -2
  289. data/spec/unit/http/client_spec.rb +74 -19
  290. data/spec/unit/http/external_client_spec.rb +9 -9
  291. data/spec/unit/http/resolver_spec.rb +24 -5
  292. data/spec/unit/http/response_spec.rb +6 -0
  293. data/spec/unit/http/service/ca_spec.rb +2 -3
  294. data/spec/unit/http/service/compiler_spec.rb +2 -3
  295. data/spec/unit/http/service/file_server_spec.rb +2 -3
  296. data/spec/unit/http/service/puppetserver_spec.rb +82 -0
  297. data/spec/unit/http/service/report_spec.rb +2 -3
  298. data/spec/unit/http/service_spec.rb +0 -1
  299. data/spec/unit/http/session_spec.rb +8 -21
  300. data/spec/unit/indirector/catalog/compiler_spec.rb +1 -0
  301. data/spec/unit/indirector/catalog/json_spec.rb +1 -1
  302. data/spec/unit/indirector/catalog/rest_spec.rb +1 -1
  303. data/spec/unit/indirector/facts/rest_spec.rb +1 -1
  304. data/spec/unit/indirector/file_metadata/http_spec.rb +194 -0
  305. data/spec/unit/indirector/file_metadata/rest_spec.rb +15 -14
  306. data/spec/unit/indirector/json_spec.rb +8 -8
  307. data/spec/unit/indirector/msgpack_spec.rb +8 -8
  308. data/spec/unit/indirector/node/rest_spec.rb +1 -1
  309. data/spec/unit/indirector/request_spec.rb +5 -5
  310. data/spec/unit/indirector/rest_spec.rb +14 -1
  311. data/spec/unit/indirector/status/rest_spec.rb +1 -1
  312. data/spec/unit/indirector/yaml_spec.rb +7 -7
  313. data/spec/unit/interface_spec.rb +3 -3
  314. data/spec/unit/module_tool/tar/mini_spec.rb +20 -0
  315. data/spec/unit/network/format_support_spec.rb +3 -2
  316. data/spec/unit/network/http/api/indirected_routes_spec.rb +2 -1
  317. data/spec/unit/network/http/api/master/v3/environments_spec.rb +12 -23
  318. data/spec/unit/network/http/connection_spec.rb +552 -190
  319. data/spec/unit/network/http/nocache_pool_spec.rb +22 -0
  320. data/spec/unit/network/http_pool_spec.rb +63 -57
  321. data/spec/unit/network/http_spec.rb +1 -1
  322. data/spec/unit/node/environment_spec.rb +18 -1
  323. data/spec/unit/parser/ast/block_expression_spec.rb +1 -1
  324. data/spec/unit/parser/environment_compiler_spec.rb +7 -0
  325. data/spec/unit/parser/scope_spec.rb +1 -1
  326. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +15 -1
  327. data/spec/unit/pops/loaders/loaders_spec.rb +71 -1
  328. data/spec/unit/pops/lookup/lookup_spec.rb +25 -0
  329. data/spec/unit/pops/types/type_calculator_spec.rb +1 -11
  330. data/spec/unit/provider/exec_spec.rb +4 -3
  331. data/spec/unit/provider/package/aix_spec.rb +29 -0
  332. data/spec/unit/provider/package/apt_spec.rb +77 -0
  333. data/spec/unit/provider/package/aptitude_spec.rb +1 -0
  334. data/spec/unit/provider/package/dnfmodule_spec.rb +25 -5
  335. data/spec/unit/provider/package/dpkg_spec.rb +22 -7
  336. data/spec/unit/provider/package/openbsd_spec.rb +2 -0
  337. data/spec/unit/provider/package/pip2_spec.rb +36 -0
  338. data/spec/unit/provider/package/pip_spec.rb +42 -16
  339. data/spec/unit/provider/package/portage_spec.rb +5 -0
  340. data/spec/unit/provider/package/puppet_gem_spec.rb +4 -1
  341. data/spec/unit/provider/package/puppetserver_gem_spec.rb +137 -0
  342. data/spec/unit/provider/package/yum_spec.rb +47 -8
  343. data/spec/unit/provider/package/zypper_spec.rb +98 -0
  344. data/spec/unit/provider/service/base_spec.rb +2 -4
  345. data/spec/unit/provider/service/bsd_spec.rb +5 -1
  346. data/spec/unit/provider/service/daemontools_spec.rb +1 -1
  347. data/spec/unit/provider/service/debian_spec.rb +3 -5
  348. data/spec/unit/provider/service/freebsd_spec.rb +1 -1
  349. data/spec/unit/provider/service/gentoo_spec.rb +4 -5
  350. data/spec/unit/provider/service/init_spec.rb +46 -5
  351. data/spec/unit/provider/service/launchd_spec.rb +5 -6
  352. data/spec/unit/provider/service/openbsd_spec.rb +9 -0
  353. data/spec/unit/provider/service/openrc_spec.rb +4 -5
  354. data/spec/unit/provider/service/openwrt_spec.rb +2 -1
  355. data/spec/unit/provider/service/redhat_spec.rb +10 -1
  356. data/spec/unit/provider/service/runit_spec.rb +2 -1
  357. data/spec/unit/provider/service/smf_spec.rb +1 -1
  358. data/spec/unit/provider/service/src_spec.rb +3 -5
  359. data/spec/unit/provider/service/systemd_spec.rb +87 -19
  360. data/spec/unit/provider/service/upstart_spec.rb +4 -5
  361. data/spec/unit/provider/service/windows_spec.rb +50 -14
  362. data/spec/unit/provider/user/openbsd_spec.rb +1 -0
  363. data/spec/unit/provider/user/useradd_spec.rb +30 -16
  364. data/spec/unit/provider/user/windows_adsi_spec.rb +82 -0
  365. data/spec/unit/puppet_pal_2pec.rb +40 -0
  366. data/spec/unit/puppet_pal_catalog_spec.rb +43 -0
  367. data/spec/unit/puppet_spec.rb +33 -0
  368. data/spec/unit/reports/http_spec.rb +1 -1
  369. data/spec/unit/reports/store_spec.rb +17 -13
  370. data/spec/unit/resource_spec.rb +3 -3
  371. data/spec/unit/rest/route_spec.rb +4 -4
  372. data/spec/unit/settings_spec.rb +182 -22
  373. data/spec/unit/ssl/ssl_provider_spec.rb +69 -43
  374. data/spec/unit/ssl/state_machine_spec.rb +52 -8
  375. data/spec/unit/test/test_helper_spec.rb +17 -0
  376. data/spec/unit/transaction/persistence_spec.rb +15 -0
  377. data/spec/unit/transaction/report_spec.rb +3 -1
  378. data/spec/unit/type/file/source_spec.rb +4 -4
  379. data/spec/unit/type/file_spec.rb +122 -96
  380. data/spec/unit/type/filebucket_spec.rb +1 -1
  381. data/spec/unit/type/service_spec.rb +218 -8
  382. data/spec/unit/type/user_spec.rb +32 -3
  383. data/spec/unit/type_spec.rb +50 -0
  384. data/spec/unit/util/autoload_spec.rb +2 -1
  385. data/spec/unit/util/character_encoding_spec.rb +4 -4
  386. data/spec/unit/util/checksums_spec.rb +16 -0
  387. data/spec/unit/util/command_line_spec.rb +11 -6
  388. data/spec/unit/util/log/destinations_spec.rb +1 -29
  389. data/spec/unit/util/package/version/range_spec.rb +22 -1
  390. data/spec/unit/util/run_mode_spec.rb +6 -6
  391. data/spec/unit/util/windows/api_types_spec.rb +104 -40
  392. data/spec/unit/util/windows/service_spec.rb +4 -4
  393. data/spec/unit/util_spec.rb +3 -3
  394. data/spec/unit/x509/cert_provider_spec.rb +1 -1
  395. data/tasks/manpages.rake +5 -35
  396. metadata +43 -49
  397. data/spec/integration/faces/config_spec.rb +0 -91
  398. data/spec/integration/faces/documentation_spec.rb +0 -57
  399. data/spec/integration/file_bucket/file_spec.rb +0 -50
  400. data/spec/integration/file_serving/content_spec.rb +0 -7
  401. data/spec/integration/file_serving/fileset_spec.rb +0 -12
  402. data/spec/integration/file_serving/metadata_spec.rb +0 -8
  403. data/spec/integration/file_serving/terminus_helper_spec.rb +0 -20
  404. data/spec/integration/file_system/uniquefile_spec.rb +0 -26
  405. data/spec/integration/module_tool/forge_spec.rb +0 -51
  406. data/spec/integration/module_tool/tar/mini_spec.rb +0 -28
  407. data/spec/integration/provider/service/init_spec.rb +0 -48
  408. data/spec/integration/provider/service/systemd_spec.rb +0 -25
  409. data/spec/integration/provider/service/windows_spec.rb +0 -50
  410. data/spec/integration/reference/providers_spec.rb +0 -21
  411. data/spec/integration/reports_spec.rb +0 -13
  412. data/spec/integration/ssl/certificate_request_spec.rb +0 -44
  413. data/spec/integration/ssl/host_spec.rb +0 -72
  414. data/spec/integration/ssl/key_spec.rb +0 -99
  415. data/spec/integration/test/test_helper_spec.rb +0 -31
  416. data/spec/shared_behaviours/file_serving_model.rb +0 -51
  417. data/spec/unit/face/man_spec.rb +0 -25
  418. data/spec/unit/man_spec.rb +0 -31
@@ -1,296 +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
113
+
114
+ context "for streaming head requests" do
115
+ it 'yields the response when request_head is called' do
116
+ stub_request(:head, url)
50
117
 
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')
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)
120
175
 
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"))
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
180
+
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)
211
+
212
+ response = subject.get(path)
213
+ expect(response).to be_an_instance_of(Net::HTTPOK)
214
+ expect(response.code).to eq("200")
215
+ end
216
+
217
+ it "returns the entire response body" do
218
+ stub_request(:get, url).to_return(body: "abc")
219
+
220
+ response = subject.get(path)
221
+ expect(response.body).to eq("abc")
222
+ end
160
223
 
161
- it "should return a 503 response if Retry-After is not convertible to an Integer or RFC 2822 Date" do
162
- retry_after('foo')
224
+ it "accepts a URL string as the path" do
225
+ url_with_query = "#{url}?foo=bar"
226
+ stub_request(:get, url_with_query)
163
227
 
164
- result = subject.get('/foo')
165
- expect(result.code).to eq("503")
228
+ response = subject.get(url_with_query)
229
+ expect(response).to be_an_instance_of(Net::HTTPOK)
230
+ end
166
231
  end
167
232
 
168
- it "should close the connection before sleeping" do
169
- retry_after('42')
233
+ context "for HEAD requests" do
234
+ it "includes default HTTP headers" do
235
+ stub_request(:head, url).with(headers: {'User-Agent' => /./})
170
236
 
171
- http1 = Net::HTTP.new(host, port)
172
- http1.use_ssl = true
173
- allow(http1).to receive(:started?).and_return(true)
237
+ subject.head(path)
238
+ end
174
239
 
175
- http2 = Net::HTTP.new(host, port)
176
- http2.use_ssl = true
177
- allow(http1).to receive(:started?).and_return(true)
240
+ it "stringifies keys and encodes values in the query" do
241
+ stub_request(:head, encoded_url_with_params)
178
242
 
179
- # The "with_connection" method is required to yield started connections
180
- pool = Puppet.lookup(:http_pool)
181
- allow(pool).to receive(:with_connection).and_yield(http1).and_yield(http2)
243
+ subject.head("#{path}?#{params.to_json}")
244
+ end
182
245
 
183
- expect(http1).to receive(:finish).ordered
184
- expect(::Kernel).to receive(:sleep).with(42).ordered
246
+ it "merges custom headers with default ones" do
247
+ stub_request(:head, url).with(headers: { 'X-Foo' => 'Bar', 'User-Agent' => /./ })
185
248
 
186
- subject.get('/foo')
187
- end
249
+ subject.head(path, {'X-Foo' => 'Bar'})
250
+ end
251
+
252
+ it "returns the response" do
253
+ stub_request(:head, url)
188
254
 
189
- it "should sleep and retry if Retry-After is an Integer" do
190
- retry_after('42')
255
+ response = subject.head(path)
256
+ expect(response).to be_an_instance_of(Net::HTTPOK)
257
+ expect(response.code).to eq("200")
258
+ end
191
259
 
192
- expect(::Kernel).to receive(:sleep).with(42)
260
+ it "accepts a URL string as the path" do
261
+ url_with_query = "#{url}?foo=bar"
262
+ stub_request(:head, url_with_query)
193
263
 
194
- result = subject.get('/foo')
195
- expect(result.code).to eq("200")
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 and retry if Retry-After is an RFC 2822 Date" 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
- now = DateTime.new(2005, 4, 13, 8, 17, 5, '-07:00')
202
- allow(DateTime).to receive(:now).and_return(now)
273
+ subject.put(path, "", {'Content-Type' => 'text/plain'})
274
+ end
203
275
 
204
- expect(::Kernel).to receive(:sleep).with(60)
276
+ it "stringifies keys and encodes values in the query" do
277
+ stub_request(:put, encoded_url_with_params)
205
278
 
206
- result = subject.get('/foo')
207
- expect(result.code).to eq("200")
208
- end
279
+ subject.put("#{path}?#{params.to_json}", "")
280
+ end
209
281
 
210
- it "should sleep for no more than the Puppet runinterval" do
211
- retry_after('60')
282
+ it "includes custom headers" do
283
+ stub_request(:put, url).with(headers: { 'X-Foo' => 'Bar' })
212
284
 
213
- Puppet[:runinterval] = 30
285
+ subject.put(path, "", {'X-Foo' => 'Bar', 'Content-Type' => 'text/plain'})
286
+ end
214
287
 
215
- expect(::Kernel).to receive(:sleep).with(30)
288
+ it "returns the response" do
289
+ stub_request(:put, url)
216
290
 
217
- subject.get('/foo')
218
- end
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"})
219
298
 
220
- it "should sleep for 0 seconds if the RFC 2822 date has past" do
221
- retry_after('Wed, 13 Apr 2005 15:18:05 GMT')
299
+ subject.put(path, "hello", {'Content-Type' => 'text/plain'})
300
+ end
222
301
 
223
- expect(::Kernel).to receive(:sleep).with(0)
302
+ it 'sends an empty body' do
303
+ stub_request(:put, url).with(body: '')
224
304
 
225
- subject.get('/foo')
226
- end
227
- end
305
+ subject.put(path, nil)
306
+ end
307
+
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
228
310
 
229
- context "basic auth" do
230
- let(:auth) { { :user => 'user', :password => 'password' } }
231
- let(:creds) { [ 'user', 'password'] }
311
+ stub_request(:put, url).with(headers: {'Content-Type' => 'application/x-www-form-urlencoded'})
232
312
 
233
- it "is allowed in get requests" do
234
- stub_request(:get, url).with(basic_auth: creds)
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)
235
319
 
236
- subject.get('/foo', nil, :basic_auth => auth)
320
+ response = subject.put(url_with_query, '')
321
+ expect(response).to be_an_instance_of(Net::HTTPOK)
322
+ end
237
323
  end
238
324
 
239
- it "is allowed in post requests" do
240
- 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
366
+
367
+ stub_request(:post, url).with(headers: {'Content-Type' => 'application/x-www-form-urlencoded'})
368
+
369
+ subject.post(path, "")
370
+ end
241
371
 
242
- subject.post('/foo', 'data', nil, :basic_auth => auth)
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
243
379
  end
244
380
 
245
- it "is allowed in head requests" do
246
- 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
399
+
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)
247
417
 
248
- subject.head('/foo', nil, :basic_auth => auth)
418
+ response = subject.delete(url_with_query)
419
+ expect(response).to be_an_instance_of(Net::HTTPOK)
420
+ end
249
421
  end
250
422
 
251
- it "is allowed in delete requests" do
252
- 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
435
+
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
253
473
 
254
- subject.delete('/foo', nil, :basic_auth => auth)
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
255
487
  end
256
488
 
257
- it "is allowed in put requests" do
258
- 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)
522
+
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
259
533
 
260
- subject.put('/foo', 'data', nil, :basic_auth => auth)
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
261
580
  end
262
- end
263
581
 
264
- it "sets HTTP User-Agent header" do
265
- puppet_ua = "Puppet/#{Puppet.version} Ruby/#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} (#{RUBY_PLATFORM})"
266
- 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'] }
267
585
 
268
- subject.get('/foo')
269
- end
586
+ it "is allowed in get requests" do
587
+ stub_request(:get, url).with(basic_auth: creds)
270
588
 
271
- describe 'connection request errors' do
272
- it "logs and raises generic http errors" do
273
- generic_error = Net::HTTPError.new('generic error', double("response"))
274
- stub_request(:get, url).to_raise(generic_error)
589
+ subject.get('/foo', nil, :basic_auth => auth)
590
+ end
275
591
 
276
- expect(Puppet).to receive(:log_exception).with(anything, /^.*failed: generic error$/)
277
- expect { subject.get('/foo') }.to raise_error(generic_error)
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)
612
+
613
+ subject.put('/foo', 'data', nil, :basic_auth => auth)
614
+ end
278
615
  end
279
616
 
280
- it "logs and raises timeout errors" do
281
- timeout_error = Timeout::Error.new
282
- 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 })
283
620
 
284
- expect(Puppet).to receive(:log_exception).with(anything, /^.*timed out after .* seconds$/)
285
- expect { subject.get('/foo') }.to raise_error(timeout_error)
621
+ subject.get('/foo')
286
622
  end
287
623
 
288
- it "logs and raises eof errors" do
289
- eof_error = EOFError
290
- 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)
291
628
 
292
- expect(Puppet).to receive(:log_exception).with(anything, /^.*interrupted after .* seconds$/)
293
- expect { subject.get('/foo') }.to raise_error(eof_error)
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)
644
+
645
+ expect(Puppet).to receive(:log_exception).with(anything, /^.*interrupted after .* seconds$/)
646
+ expect { subject.get('/foo') }.to raise_error(eof_error)
647
+ end
294
648
  end
295
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
296
658
  end