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
@@ -197,7 +197,7 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
197
197
  end
198
198
 
199
199
  context 'when locking' do
200
- let(:lockfile) { double('ssllockfile') }
200
+ let(:lockfile) { Puppet::Util::Pidlock.new(Puppet[:ssl_lockfile]) }
201
201
  let(:machine) { described_class.new(cert_provider: cert_provider, ssl_provider: ssl_provider, lockfile: lockfile) }
202
202
 
203
203
  # lockfile is deleted before `ensure_ca_certificates` returns, so
@@ -210,7 +210,7 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
210
210
  end
211
211
 
212
212
  it 'locks the file prior to running the state machine and unlocks when done' do
213
- expect(lockfile).to receive(:lock).and_return(true).ordered
213
+ expect(lockfile).to receive(:lock).and_call_original.ordered
214
214
  expect(cert_provider).to receive(:load_cacerts).and_return(cacerts).ordered
215
215
  expect(cert_provider).to receive(:load_crls).and_return(crls).ordered
216
216
  expect(lockfile).to receive(:unlock).ordered
@@ -228,13 +228,6 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
228
228
  expect(File).to_not be_exist(Puppet[:ssl_lockfile])
229
229
  end
230
230
 
231
- it 'raises an exception when locking fails' do
232
- allow(lockfile).to receive(:lock).and_return(false)
233
- expect {
234
- machine.ensure_ca_certificates
235
- }.to raise_error(Puppet::Error, /Another puppet instance is already running; exiting/)
236
- end
237
-
238
231
  it 'acquires an empty lockfile' do
239
232
  Puppet::FileSystem.touch(Puppet[:ssl_lockfile])
240
233
 
@@ -262,6 +255,57 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
262
255
  machine = described_class.new(cert_provider: cert_provider, ssl_provider: ssl_provider)
263
256
  machine.ensure_ca_certificates
264
257
  end
258
+
259
+ context 'and another puppet process is running' do
260
+ let(:now) { Time.now }
261
+ let(:future) { now + (5 * 60)} # 5 mins in the future
262
+
263
+ before :each do
264
+ allow(lockfile).to receive(:lock).and_return(false)
265
+ end
266
+
267
+ it 'raises a puppet exception' do
268
+ expect {
269
+ machine.ensure_ca_certificates
270
+ }.to raise_error(Puppet::Error, /Another puppet instance is already running and the waitforlock setting is set to 0; exiting/)
271
+ end
272
+
273
+ it 'sleeps and retries successfully' do
274
+ machine = described_class.new(lockfile: lockfile, cert_provider: cert_provider, waitforlock: 1, maxwaitforlock: 10)
275
+ allow(cert_provider).to receive(:load_cacerts).and_return(cacerts)
276
+ allow(cert_provider).to receive(:load_crls).and_return(crls)
277
+ allow(Time).to receive(:now).and_return(now, future)
278
+
279
+ expect(Kernel).to receive(:sleep).with(1)
280
+ expect(Puppet).to receive(:info).with("Another puppet instance is already running; waiting for it to finish")
281
+ expect(Puppet).to receive(:info).with("Will try again in 1 seconds.")
282
+
283
+ allow(lockfile).to receive(:lock).and_return(false, true)
284
+
285
+ expect(machine.ensure_ca_certificates).to be_an_instance_of(Puppet::SSL::SSLContext)
286
+ end
287
+
288
+ it 'sleeps and retries unsuccessfully until the deadline is exceeded' do
289
+ machine = described_class.new(lockfile: lockfile, waitforlock: 1, maxwaitforlock: 10)
290
+ allow(Time).to receive(:now).and_return(now, future)
291
+
292
+ expect(Kernel).to receive(:sleep).with(1)
293
+ expect(Puppet).to receive(:info).with("Another puppet instance is already running; waiting for it to finish")
294
+ expect(Puppet).to receive(:info).with("Will try again in 1 seconds.")
295
+
296
+ allow(lockfile).to receive(:lock).and_return(false)
297
+ expect {
298
+ machine.ensure_ca_certificates
299
+ }.to raise_error(Puppet::Error, /Another puppet instance is already running and the maxwaitforlock timeout has been exceeded; exiting/)
300
+ end
301
+
302
+ it 'defaults the waitlock deadline to 60 seconds' do
303
+ allow(Time).to receive(:now).and_return(now)
304
+
305
+ machine = described_class.new
306
+ expect(machine.waitlock_deadline).to eq(now.to_i + 60)
307
+ end
308
+ end
265
309
  end
266
310
 
267
311
  context 'NeedCACerts' do
@@ -837,7 +881,7 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
837
881
  }.to output(/Exiting now because the waitforcert setting is set to 0./).to_stdout
838
882
  end
839
883
 
840
- it 'sleeps and transitions to NeedCACerts' do
884
+ it 'sleeps and transitions to NeedLock' do
841
885
  machine = described_class.new(waitforcert: 15)
842
886
 
843
887
  state = Puppet::SSL::StateMachine::Wait.new(machine)
@@ -845,10 +889,10 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
845
889
 
846
890
  expect(Puppet).to receive(:info).with(/Will try again in 15 seconds./)
847
891
 
848
- expect(state.next_state).to be_an_instance_of(Puppet::SSL::StateMachine::NeedCACerts)
892
+ expect(state.next_state).to be_an_instance_of(Puppet::SSL::StateMachine::NeedLock)
849
893
  end
850
894
 
851
- it 'sleeps and transitions to NeedCACerts when maxwaitforcert is set' do
895
+ it 'sleeps and transitions to NeedLock when maxwaitforcert is set' do
852
896
  machine = described_class.new(waitforcert: 15, maxwaitforcert: 30)
853
897
 
854
898
  state = Puppet::SSL::StateMachine::Wait.new(machine)
@@ -856,7 +900,7 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
856
900
 
857
901
  expect(Puppet).to receive(:info).with(/Will try again in 15 seconds./)
858
902
 
859
- expect(state.next_state).to be_an_instance_of(Puppet::SSL::StateMachine::NeedCACerts)
903
+ expect(state.next_state).to be_an_instance_of(Puppet::SSL::StateMachine::NeedLock)
860
904
  end
861
905
 
862
906
  it 'waits indefinitely by default' do
@@ -877,6 +921,48 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
877
921
  }.to exit_with(1)
878
922
  }.to output(/Couldn't fetch certificate from CA server; you might still need to sign this agent's certificate \(.*\). Exiting now because the maxwaitforcert timeout has been exceeded./).to_stdout
879
923
  end
924
+
925
+ it 'closes the pool before sleeping' do
926
+ machine = described_class.new(waitforcert: 15)
927
+
928
+ state = Puppet::SSL::StateMachine::Wait.new(machine)
929
+ expect(Puppet.runtime[:http].pool).to receive(:close).and_call_original
930
+ expect(Kernel).to receive(:sleep).with(15).ordered
931
+
932
+ state.next_state
933
+ end
934
+
935
+ it 'releases the lock while sleeping' do
936
+ lockfile = Puppet::Util::Pidlock.new(Puppet[:ssl_lockfile])
937
+ machine = described_class.new(lockfile: lockfile)
938
+ state = Puppet::SSL::StateMachine::Wait.new(machine)
939
+
940
+ # pidlock should be unlocked while sleeping
941
+ allow(Kernel).to receive(:sleep) do
942
+ expect(lockfile).to_not be_locked
943
+ end
944
+
945
+ # lock before running the state
946
+ lockfile.lock
947
+ state.next_state
948
+ end
949
+ end
950
+
951
+ context 'in state NeedLock' do
952
+ let(:ssl_context) { Puppet::SSL::SSLContext.new(cacerts: []) }
953
+ let(:lockfile) { Puppet::Util::Pidlock.new(Puppet[:ssl_lockfile]) }
954
+ let(:machine) { described_class.new(lockfile: lockfile) }
955
+ let(:state) { Puppet::SSL::StateMachine::NeedLock.new(machine) }
956
+
957
+ it 'acquires the lock and transitions to NeedCACerts' do
958
+ expect(state.next_state).to be_an_instance_of(Puppet::SSL::StateMachine::NeedCACerts)
959
+ expect(lockfile).to be_locked
960
+ end
961
+
962
+ it 'transitions to LockFailure if it fails to acquire the lock' do
963
+ expect(lockfile).to receive(:lock).and_return(false)
964
+ expect(state.next_state).to be_an_instance_of(Puppet::SSL::StateMachine::LockFailure)
965
+ end
880
966
  end
881
967
  end
882
968
  end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe "TestHelper" do
4
+ context "#after_each_test" do
5
+ it "restores the original environment" do
6
+ varname = 'test_helper_spec-test_variable'
7
+ Puppet::Util.set_env(varname, "\u16A0")
8
+
9
+ expect(Puppet::Util.get_env(varname)).to eq("\u16A0")
10
+
11
+ # Prematurely trigger the after_each_test method
12
+ Puppet::Test::TestHelper.after_each_test
13
+
14
+ expect(Puppet::Util::get_env(varname)).to be_nil
15
+ end
16
+ end
17
+ end
@@ -146,16 +146,7 @@ describe Puppet::Transaction::Persistence do
146
146
  Dir.mkdir(Puppet[:transactionstorefile])
147
147
  persistence = Puppet::Transaction::Persistence.new
148
148
 
149
- if Puppet::Util::Platform.windows?
150
- expect do
151
- persistence.save
152
- end.to raise_error do |error|
153
- expect(error).to be_a(Puppet::Util::Windows::Error)
154
- expect(error.code).to eq(5) # ERROR_ACCESS_DENIED
155
- end
156
- else
157
- expect { persistence.save }.to raise_error(Errno::EISDIR, /Is a directory/)
158
- end
149
+ expect { persistence.save }.to raise_error(Errno::EISDIR, /Is a directory/)
159
150
 
160
151
  Dir.rmdir(Puppet[:transactionstorefile])
161
152
  end
@@ -39,6 +39,10 @@ describe Puppet::Transaction::Report do
39
39
  expect(Puppet::Transaction::Report.new('cv', 'env', 'tid', 'some job id').job_id).to eq('some job id')
40
40
  end
41
41
 
42
+ it "should take a 'start_time' as an argument" do
43
+ expect(Puppet::Transaction::Report.new('cv', 'env', 'tid', 'some job id', 'my start time').time).to eq('my start time')
44
+ end
45
+
42
46
  it "should be able to set configuration_version" do
43
47
  report = Puppet::Transaction::Report.new
44
48
  report.configuration_version = "some version"
@@ -659,7 +663,7 @@ Version:
659
663
  :status => stringifier.convert('success'),
660
664
  }
661
665
 
662
- event = Puppet::Transaction::Event.new(event_hash)
666
+ event = Puppet::Transaction::Event.new(**event_hash)
663
667
 
664
668
  status = Puppet::Resource::Status.new(Puppet::Type.type(:notify).new(:title => "a resource"))
665
669
  status.changed = true
@@ -3,8 +3,6 @@ require 'matchers/include_in_order'
3
3
  require 'puppet_spec/compiler'
4
4
 
5
5
  require 'puppet/transaction'
6
- require 'puppet/type/exec'
7
- require 'puppet/type/notify'
8
6
  require 'fileutils'
9
7
 
10
8
  describe Puppet::Transaction do
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
- require 'puppet/type/file/ensure'
3
2
 
4
- describe Puppet::Type::File::Ensure do
3
+ describe Puppet::Type.type(:file).attrclass(:ensure) do
5
4
  include PuppetSpec::Files
6
5
 
7
6
  let(:path) { tmpfile('file_ensure') }
@@ -22,8 +22,8 @@ describe Puppet::Type.type(:file).attrclass(:source), :uses_checksums => true do
22
22
  @foobar = make_absolute("/foo/bar baz")
23
23
  @feebooz = make_absolute("/fee/booz baz")
24
24
 
25
- @foobar_uri = URI.unescape(Puppet::Util.path_to_uri(@foobar).to_s)
26
- @feebooz_uri = URI.unescape(Puppet::Util.path_to_uri(@feebooz).to_s)
25
+ @foobar_uri = Puppet::Util.uri_unescape(Puppet::Util.path_to_uri(@foobar).to_s)
26
+ @feebooz_uri = Puppet::Util.uri_unescape(Puppet::Util.path_to_uri(@feebooz).to_s)
27
27
  end
28
28
 
29
29
  it "should be a subclass of Parameter" do
@@ -82,7 +82,7 @@ describe Puppet::Type.type(:file).attrclass(:source), :uses_checksums => true do
82
82
  describe "#munge" do
83
83
  it "should prefix file scheme to absolute paths" do
84
84
  resource[:source] = filename
85
- expect(resource[:source]).to eq([URI.unescape(Puppet::Util.path_to_uri(filename).to_s)])
85
+ expect(resource[:source]).to eq([Puppet::Util.uri_unescape(Puppet::Util.path_to_uri(filename).to_s)])
86
86
  end
87
87
 
88
88
  %w[file puppet].each do |scheme|
@@ -533,20 +533,54 @@ describe Puppet::Type.type(:file).attrclass(:source), :uses_checksums => true do
533
533
  describe "when writing" do
534
534
  describe "as puppet apply" do
535
535
  let(:source_content) { "source file content\r\n"*10 }
536
+ let(:modulepath) { File.join(Puppet[:environmentpath], 'testing', 'modules') }
537
+ let(:env) { Puppet::Node::Environment.create(:testing, [modulepath]) }
538
+ let(:catalog) { Puppet::Resource::Catalog.new(:test, env) }
539
+
536
540
  before do
537
541
  Puppet[:default_file_terminus] = "file_server"
538
- resource[:source] = file_containing('apply', source_content)
539
542
  end
540
543
 
541
544
  it "should copy content from the source to the file" do
545
+ resource = Puppet::Type.type(:file).new(path: filename, catalog: catalog, source: file_containing('apply', source_content))
542
546
  source = resource.parameter(:source)
543
547
  resource.write(source)
544
548
 
545
549
  expect(Puppet::FileSystem.binread(filename)).to eq(source_content)
546
550
  end
547
551
 
552
+ it 'should use the in-process fileserver if source starts with puppet:///' do
553
+ path = File.join(modulepath, 'mymodule', 'files', 'path')
554
+ Puppet::FileSystem.dir_mkpath(path)
555
+ File.open(path, 'wb') { |f| f.write(source_content) }
556
+ resource = Puppet::Type.type(:file).new(path: filename, catalog: catalog, source: 'puppet:///modules/mymodule/path')
557
+
558
+ source = resource.parameter(:source)
559
+ resource.write(source)
560
+
561
+ expect(Puppet::FileSystem.binread(filename)).to eq(source_content)
562
+ end
563
+
564
+ it 'follows symlinks when retrieving content from the in-process fileserver' do
565
+ # create a 'link' that points to 'target' in the 'mymodule' module
566
+ link = File.join(modulepath, 'mymodule', 'files', 'link')
567
+ target = File.join(modulepath, 'mymodule', 'files', 'target')
568
+ Puppet::FileSystem.dir_mkpath(target)
569
+ File.open(target, 'wb') { |f| f.write(source_content) }
570
+ Puppet::FileSystem.symlink(target, link)
571
+ resource = Puppet::Type.type(:file).new(path: filename, catalog: catalog, source: 'puppet:///modules/mymodule/link')
572
+
573
+ source = resource.parameter(:source)
574
+ resource.write(source)
575
+
576
+ # 'filename' should be a file containing the contents of the followed link
577
+ expect(Puppet::FileSystem.binread(filename)).to eq(source_content)
578
+ end
579
+
548
580
  with_digest_algorithms do
549
581
  it "should return the checksum computed" do
582
+ resource = Puppet::Type.type(:file).new(path: filename, catalog: catalog, source: file_containing('apply', source_content))
583
+
550
584
  File.open(filename, 'wb') do |file|
551
585
  source = resource.parameter(:source)
552
586
  resource[:checksum] = digest_algorithm
@@ -583,53 +617,73 @@ describe Puppet::Type.type(:file).attrclass(:source), :uses_checksums => true do
583
617
 
584
618
  describe 'from remote source' do
585
619
  let(:source_content) { "source file content\n"*10 }
586
- let(:source) { resource.newattr(:source) }
587
- let(:response) { double('response', :[] => nil, :body => nil, :message => nil) }
588
- let(:conn) { double('connection') }
620
+ let(:source) {
621
+ attr = resource.newattr(:source)
622
+ attr.metadata = metadata
623
+ attr
624
+ }
625
+ let(:metadata) {
626
+ Puppet::FileServing::Metadata.new(
627
+ '/modules/:module/foo',
628
+ {
629
+ 'type' => 'file',
630
+ 'source' => 'puppet:///modules/:module/foo'
631
+ }
632
+ )
633
+ }
589
634
 
590
635
  before do
591
636
  resource[:backup] = false
592
-
593
- expectation = receive(:read_body)
594
- source_content.lines.each { |line| expectation = expectation.and_yield(line) }
595
- allow(response).to expectation
596
- allow(conn).to receive(:request_get).and_yield(response)
597
637
  end
598
638
 
599
639
  it 'should use an explicit fileserver if source starts with puppet://' do
600
- allow(response).to receive(:code).and_return('200')
601
- allow(source).to receive(:metadata).and_return(double('metadata', :source => 'puppet://somehostname/test/foo', :ftype => 'file', :content_uri => nil))
602
- expect(Puppet::Network::HttpPool).to receive(:connection).with('somehostname', 8140, anything).and_return(conn)
640
+ metadata.source = "puppet://somehostname:8140/modules/:module/foo"
641
+
642
+ stub_request(:get, %r{https://somehostname:8140/puppet/v3/file_content/modules/:module/foo})
643
+ .to_return(status: 200, body: metadata.to_json, headers: { 'Content-Type' => 'application/json' })
603
644
 
604
645
  resource.write(source)
605
646
  end
606
647
 
607
648
  it 'should use the default fileserver if source starts with puppet:///' do
608
- allow(response).to receive(:code).and_return('200')
609
- allow(source).to receive(:metadata).and_return(double('metadata', :source => 'puppet:///test/foo', :ftype => 'file', :content_uri => nil))
610
- expect(Puppet::Network::HttpPool).to receive(:connection).with(Puppet[:server], 8140, anything).and_return(conn)
649
+ stub_request(:get, %r{https://#{Puppet[:server]}:8140/puppet/v3/file_content/modules/:module/foo})
650
+ .to_return(status: 200, body: metadata.to_json, headers: { 'Content-Type' => 'application/json' })
611
651
 
612
652
  resource.write(source)
613
653
  end
614
654
 
615
655
  it 'should percent encode reserved characters' do
616
- allow(response).to receive(:code).and_return('200')
617
- allow(Puppet::Network::HttpPool).to receive(:connection).and_return(conn)
618
- allow(source).to receive(:metadata).and_return(double('metadata', :source => 'puppet:///test/foo bar', :ftype => 'file', :content_uri => nil))
656
+ metadata.source = 'puppet:///modules/:module/foo bar'
619
657
 
620
- expect(conn).to receive(:request_get).with("#{Puppet::Network::HTTP::MASTER_URL_PREFIX}/v3/file_content/test/foo%20bar?environment=myenv&", anything).and_yield(response)
658
+ stub_request(:get, %r{/puppet/v3/file_content/modules/:module/foo%20bar})
659
+ .to_return(status: 200, body: metadata.to_json, headers: { 'Content-Type' => 'application/json' })
621
660
 
622
661
  resource.write(source)
623
662
  end
624
663
 
625
664
  it 'should request binary content' do
626
- allow(response).to receive(:code).and_return('200')
627
- allow(Puppet::Network::HttpPool).to receive(:connection).and_return(conn)
628
- allow(source).to receive(:metadata).and_return(double('metadata', :source => 'puppet:///test/foo bar', :ftype => 'file', :content_uri => nil))
665
+ stub_request(:get, %r{/puppet/v3/file_content/modules/:module/foo}) do |request|
666
+ expect(request.headers).to include({'Accept' => 'application/octet-stream'})
667
+ end.to_return(status: 200, body: '', headers: { 'Content-Type' => 'application/octet-stream' })
629
668
 
630
- expect(conn).to receive(:request_get) do |_, options|
631
- expect(options).to include('Accept' => 'application/octet-stream')
632
- end.and_yield(response)
669
+ resource.write(source)
670
+ end
671
+
672
+ it "should request file content from the catalog's environment" do
673
+ Puppet[:environment] = 'doesntexist'
674
+
675
+ stub_request(:get, %r{/puppet/v3/file_content})
676
+ .with(query: hash_including("environment" => "myenv"))
677
+ .to_return(status: 200, body: '', headers: { 'Content-Type' => 'application/octet-stream' })
678
+
679
+ resource.write(source)
680
+ end
681
+
682
+ it 'should request static file content' do
683
+ metadata.content_uri = "puppet://#{Puppet[:server]}:8140/path/to/file"
684
+
685
+ stub_request(:get, %r{/puppet/v3/static_file_content/path/to/file})
686
+ .to_return(status: 200, body: '', headers: { 'Content-Type' => 'application/octet-stream' })
633
687
 
634
688
  resource.write(source)
635
689
  end
@@ -639,26 +693,23 @@ describe Puppet::Type.type(:file).attrclass(:source), :uses_checksums => true do
639
693
  File.open(filename, 'w') {|f| f.write "initial file content"}
640
694
  end
641
695
 
642
- before(:each) do
643
- allow(Puppet::Network::HttpPool).to receive(:connection).and_return(conn)
644
- allow(source).to receive(:metadata).and_return(double('metadata', :source => 'puppet:///test/foo', :ftype => 'file', :content_uri => nil))
645
- end
646
-
647
696
  it 'should not write anything if source is not found' do
648
- allow(response).to receive(:code).and_return('404')
697
+ stub_request(:get, %r{/puppet/v3/file_content/modules/:module/foo}).to_return(status: 404)
649
698
 
650
- expect { resource.write(source) }.to raise_error(Net::HTTPError, /404/)
699
+ expect { resource.write(source) }.to raise_error(Net::HTTPError, /Error 404 on SERVER:/)
651
700
  expect(File.read(filename)).to eq('initial file content')
652
701
  end
653
702
 
654
703
  it 'should raise an HTTP error in case of server error' do
655
- allow(response).to receive(:code).and_return('500')
704
+ stub_request(:get, %r{/puppet/v3/file_content/modules/:module/foo}).to_return(status: 500)
656
705
 
657
- expect { resource.write(source) }.to raise_error(Net::HTTPError, /500/)
706
+ expect { resource.write(source) }.to raise_error(Net::HTTPError, /Error 500 on SERVER/)
658
707
  end
659
708
 
660
709
  context 'and the request was successful' do
661
- before(:each) { allow(response).to receive(:code).and_return('200') }
710
+ before do
711
+ stub_request(:get, %r{/puppet/v3/file_content/modules/:module/foo}).to_return(status: 200, body: source_content)
712
+ end
662
713
 
663
714
  it 'should write the contents to the file' do
664
715
  resource.write(source)
@@ -3,6 +3,34 @@ require 'spec_helper'
3
3
  describe Puppet::Type.type(:file) do
4
4
  include PuppetSpec::Files
5
5
 
6
+ # precomputed checksum values for FILE_CONTENT
7
+ FILE_CONTENT = 'file content'.freeze
8
+ CHECKSUM_VALUES = {
9
+ md5: 'd10b4c3ff123b26dc068d43a8bef2d23',
10
+ md5lite: 'd10b4c3ff123b26dc068d43a8bef2d23',
11
+ sha256: 'e0ac3601005dfa1864f5392aabaf7d898b1b5bab854f1acb4491bcd806b76b0c',
12
+ sha256lite: 'e0ac3601005dfa1864f5392aabaf7d898b1b5bab854f1acb4491bcd806b76b0c',
13
+ sha1: '87758871f598e1a3b4679953589ae2f57a0bb43c',
14
+ sha1lite: '87758871f598e1a3b4679953589ae2f57a0bb43c',
15
+ sha224: '2aefaaa5f4d8f17f82f3e1bb407e190cede9aa1311fa4533ce505531',
16
+ sha384: '61c7783501ebd90233650357fefbe5a141b7618f907b8f043bbaa92c0f610c785a641ddd479fa81d650cd86e29aa6858',
17
+ sha512: '2fb1877301854ac92dd518018f97407a0a88bb696bfef0a51e9efbd39917353500009e15bd72c3f0e4bf690115870bfab926565d5ad97269d922dbbb41261221',
18
+ mtime: 'Jan 26 13:59:49 2016',
19
+ ctime: 'Jan 26 13:59:49 2016'
20
+ }.freeze
21
+
22
+ INVALID_CHECKSUM_VALUES = {
23
+ md5: '00000000000000000000000000000000',
24
+ md5lite: '00000000000000000000000000000000',
25
+ sha256: '0000000000000000000000000000000000000000000000000000000000000000',
26
+ sha256lite: '0000000000000000000000000000000000000000000000000000000000000000',
27
+ sha1: '0000000000000000000000000000000000000000',
28
+ sha1lite: '0000000000000000000000000000000000000000',
29
+ sha224: '00000000000000000000000000000000000000000000000000000000',
30
+ sha384: '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
31
+ sha512: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
32
+ }.freeze
33
+
6
34
  let(:path) { tmpfile('file_testing') }
7
35
  let(:file) { described_class.new(:path => path, :catalog => catalog) }
8
36
  let(:provider) { file.provider }
@@ -791,7 +819,7 @@ describe Puppet::Type.type(:file) do
791
819
  let(:sources) do
792
820
  h = {}
793
821
  %w{/a /b /c /d}.each do |key|
794
- h[key] = URI.unescape(Puppet::Util.path_to_uri(File.expand_path(key)).to_s)
822
+ h[key] = Puppet::Util.uri_unescape(Puppet::Util.path_to_uri(File.expand_path(key)).to_s)
795
823
  end
796
824
  h
797
825
  end
@@ -1108,38 +1136,6 @@ describe Puppet::Type.type(:file) do
1108
1136
  end
1109
1137
 
1110
1138
  describe "#write" do
1111
- describe "when validating the checksum" do
1112
- before { allow(file).to receive(:validate_checksum?).and_return(true) }
1113
-
1114
- it "should fail if the checksum parameter and content checksums do not match" do
1115
- checksum = double('checksum_parameter', :sum => 'checksum_b', :sum_file => 'checksum_b')
1116
- allow(file).to receive(:parameter).with(:checksum).and_return(checksum)
1117
- allow(file).to receive(:parameter).with(:source).and_return(nil)
1118
-
1119
-
1120
- property = double('content_property', :actual_content => "something", :length => "something".length, :write => 'checksum_a')
1121
- allow(file).to receive(:property).with(:content).and_return(property)
1122
-
1123
- expect { file.write property }.to raise_error(Puppet::Error) end
1124
- end
1125
-
1126
- describe "when not validating the checksum" do
1127
- before do
1128
- allow(file).to receive(:validate_checksum?).and_return(false)
1129
- end
1130
-
1131
- it "should not fail if the checksum property and content checksums do not match" do
1132
- checksum = double('checksum_parameter', :sum => 'checksum_b')
1133
- allow(file).to receive(:parameter).with(:checksum).and_return(checksum)
1134
- allow(file).to receive(:parameter).with(:source).and_return(nil)
1135
-
1136
- property = double('content_property', :actual_content => "something", :length => "something".length, :write => 'checksum_a')
1137
- allow(file).to receive(:property).with(:content).and_return(property)
1138
-
1139
- expect { file.write property }.to_not raise_error
1140
- end
1141
- end
1142
-
1143
1139
  describe "when resource mode is supplied" do
1144
1140
  before do
1145
1141
  allow(file).to receive(:property_fix)
@@ -1191,7 +1187,7 @@ describe Puppet::Type.type(:file) do
1191
1187
  describe "when resource mode is not supplied" do
1192
1188
  context "and content is supplied" do
1193
1189
  it "should default to 0644 mode" do
1194
- file = described_class.new(:path => path, :content => "file content")
1190
+ file = described_class.new(:path => path, :content => FILE_CONTENT)
1195
1191
 
1196
1192
  file.write file.parameter(:content)
1197
1193
 
@@ -1214,35 +1210,6 @@ describe Puppet::Type.type(:file) do
1214
1210
  end
1215
1211
  end
1216
1212
 
1217
- describe "#fail_if_checksum_is_wrong" do
1218
- it "should fail if the checksum of the file doesn't match the expected one" do
1219
- expect do
1220
- allow(file.parameter(:checksum)).to receive(:sum_file).and_return('wrong!!')
1221
- file.instance_eval do
1222
- fail_if_checksum_is_wrong(self[:path], 'anything!')
1223
- end
1224
- end.to raise_error(Puppet::Error, /File written to disk did not match checksum/)
1225
- end
1226
-
1227
- it "should not fail if the checksum is correct" do
1228
- expect do
1229
- allow(file.parameter(:checksum)).to receive(:sum_file).and_return('anything!')
1230
- file.instance_eval do
1231
- fail_if_checksum_is_wrong(self[:path], 'anything!')
1232
- end
1233
- end.not_to raise_error
1234
- end
1235
-
1236
- it "should not fail if the checksum is absent" do
1237
- expect do
1238
- allow(file.parameter(:checksum)).to receive(:sum_file).and_return(nil)
1239
- file.instance_eval do
1240
- fail_if_checksum_is_wrong(self[:path], 'anything!')
1241
- end
1242
- end.not_to raise_error
1243
- end
1244
- end
1245
-
1246
1213
  describe "#write_temporary_file?" do
1247
1214
  it "should be true if the file has specified content" do
1248
1215
  file[:content] = 'some content'
@@ -1462,7 +1429,7 @@ describe Puppet::Type.type(:file) do
1462
1429
  expect(Puppet::FileServing::Metadata.indirection).to receive(:find).with(source, anything).and_return(metadata)
1463
1430
 
1464
1431
  uri = file.parameters[:source].uri
1465
- expect(URI.unescape(uri.path)).to eq(filename)
1432
+ expect(Puppet::Util.uri_unescape(uri.path)).to eq(filename)
1466
1433
  expect(uri.path.encoding).to eq(Encoding::UTF_8)
1467
1434
  end
1468
1435
 
@@ -1486,29 +1453,16 @@ describe Puppet::Type.type(:file) do
1486
1453
  expect_any_instance_of(Puppet::Indirector::FileMetadata::Rest).to receive(:find).with(request_key(filename[1..-1])).and_return(metadata)
1487
1454
 
1488
1455
  uri = file.parameters[:source].uri
1489
- expect(URI.unescape(uri.path)).to eq(filename)
1456
+ expect(Puppet::Util.uri_unescape(uri.path)).to eq(filename)
1490
1457
  expect(uri.path.encoding).to eq(Encoding::UTF_8)
1491
1458
  end
1492
1459
  end
1493
1460
 
1494
1461
  describe "when using source" do
1462
+ let(:source) { tmpfile('file_source') }
1463
+
1495
1464
  before do
1496
- file[:source] = File.expand_path('/one')
1497
- # Contents of an empty file generate the below hash values
1498
- # in case you need to add support for additional algorithms in future
1499
- @checksum_values = {
1500
- :md5 => 'd41d8cd98f00b204e9800998ecf8427e',
1501
- :md5lite => 'd41d8cd98f00b204e9800998ecf8427e',
1502
- :sha256 => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
1503
- :sha256lite => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
1504
- :sha1 => 'da39a3ee5e6b4b0d3255bfef95601890afd80709',
1505
- :sha1lite => 'da39a3ee5e6b4b0d3255bfef95601890afd80709',
1506
- :sha224 => 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f',
1507
- :sha384 => '38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b',
1508
- :sha512 => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e',
1509
- :mtime => 'Jan 26 13:59:49 2016',
1510
- :ctime => 'Jan 26 13:59:49 2016'
1511
- }
1465
+ file[:source] = source
1512
1466
  end
1513
1467
 
1514
1468
  Puppet::Type::File::ParameterChecksum.value_collection.values.reject {|v| v == :none}.each do |checksum_type|
@@ -1527,9 +1481,51 @@ describe Puppet::Type.type(:file) do
1527
1481
  end
1528
1482
 
1529
1483
  it 'should validate a valid checksum_value' do
1530
- file[:checksum_value] = @checksum_values[checksum_type]
1484
+ file[:checksum_value] = CHECKSUM_VALUES[checksum_type]
1531
1485
  expect { file.validate }.to_not raise_error
1532
1486
  end
1487
+
1488
+ it 'fails if the checksum_value parameter and written file do not match' do
1489
+ skip if checksum_type =~ /^(ctime|mtime)/
1490
+
1491
+ File.write(source, FILE_CONTENT)
1492
+ file[:checksum_value] = INVALID_CHECKSUM_VALUES[checksum_type]
1493
+
1494
+ expect {
1495
+ file.property(:checksum_value).sync
1496
+ }.to raise_error(Puppet::Error, /File written to disk did not match desired checksum/)
1497
+
1498
+ expect(Puppet::FileSystem).to_not be_exist(file[:path])
1499
+ end
1500
+
1501
+ it 'fails if the checksum_value parameter does not match, but the metadata does' do
1502
+ skip if checksum_type =~ /^(ctime|mtime)/
1503
+
1504
+ File.write(source, FILE_CONTENT)
1505
+ file[:checksum_value] = INVALID_CHECKSUM_VALUES[checksum_type]
1506
+ allow(file.parameter(:source).metadata).to receive(:checksum).and_return(file[:checksum_value])
1507
+
1508
+ expect {
1509
+ file.property(:checksum_value).sync
1510
+ }.to raise_error(Puppet::Error, /File written to disk did not match desired checksum/)
1511
+
1512
+ expect(Puppet::FileSystem).to_not be_exist(file[:path])
1513
+ end
1514
+
1515
+ it 'replaces a file from a source when the checksum matches' do
1516
+ File.write(source, FILE_CONTENT)
1517
+ file[:checksum_value] = CHECKSUM_VALUES[checksum_type]
1518
+
1519
+ file.property(:checksum_value).sync
1520
+ checksum = file.parameter(:checksum).sum_file(file[:path])
1521
+
1522
+ if checksum_type =~ /^(ctime|mtime)/
1523
+ # file on disk ctime/mtime will be later than expected time
1524
+ expect(checksum).to match(/{#{checksum_type}}/)
1525
+ else
1526
+ expect(checksum).to eq("{#{checksum_type}}#{file[:checksum_value]}")
1527
+ end
1528
+ end
1533
1529
  end
1534
1530
  end
1535
1531
 
@@ -1591,19 +1587,8 @@ describe Puppet::Type.type(:file) do
1591
1587
  end
1592
1588
 
1593
1589
  describe "when using content" do
1594
- before do
1595
- file[:content] = 'file contents'
1596
- @checksum_values = {
1597
- :md5 => 'd41d8cd98f00b204e9800998ecf8427e',
1598
- :md5lite => 'd41d8cd98f00b204e9800998ecf8427e',
1599
- :sha256 => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
1600
- :sha256lite => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
1601
- :sha1 => 'da39a3ee5e6b4b0d3255bfef95601890afd80709',
1602
- :sha1lite => 'da39a3ee5e6b4b0d3255bfef95601890afd80709',
1603
- :sha224 => 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f',
1604
- :sha384 => '38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b',
1605
- :sha512 => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e',
1606
- }
1590
+ before :each do
1591
+ file[:content] = FILE_CONTENT
1607
1592
  end
1608
1593
 
1609
1594
  (Puppet::Type::File::ParameterChecksum.value_collection.values - SOURCE_ONLY_CHECKSUMS).each do |checksum_type|
@@ -1622,9 +1607,43 @@ describe Puppet::Type.type(:file) do
1622
1607
  end
1623
1608
 
1624
1609
  it 'should validate a valid checksum_value' do
1625
- file[:checksum_value] = @checksum_values[checksum_type]
1610
+ file[:checksum_value] = CHECKSUM_VALUES[checksum_type]
1626
1611
  expect { file.validate }.to_not raise_error
1627
1612
  end
1613
+
1614
+ it 'fails if the checksum_value parameter and written file do not match' do
1615
+ file[:checksum_value] = INVALID_CHECKSUM_VALUES[checksum_type]
1616
+
1617
+ expect {
1618
+ file.property(:content).sync
1619
+ }.to raise_error(Puppet::Error, /File written to disk did not match desired checksum/)
1620
+
1621
+ expect(Puppet::FileSystem).to_not be_exist(file[:path])
1622
+ end
1623
+
1624
+ it 'fails if the calculated checksum for the content and written file do not match' do
1625
+ allow(file.parameter(:checksum)).to receive(:sum).and_return(INVALID_CHECKSUM_VALUES[checksum_type])
1626
+
1627
+ expect {
1628
+ file.property(:content).sync
1629
+ }.to raise_error(Puppet::Error, /File written to disk did not match desired checksum/)
1630
+
1631
+ expect(Puppet::FileSystem).to_not be_exist(file[:path])
1632
+ end
1633
+
1634
+ it 'replaces a file from content when the checksum matches' do
1635
+ file[:checksum_value] = CHECKSUM_VALUES[checksum_type]
1636
+
1637
+ file.property(:content).sync
1638
+ checksum = file.parameter(:checksum).sum_file(file[:path])
1639
+
1640
+ if checksum_type =~ /^(ctime|mtime)/
1641
+ # file on disk ctime/mtime will be later than expected time
1642
+ expect(checksum).to match(/{#{checksum_type}}/)
1643
+ else
1644
+ expect(checksum).to eq("{#{checksum_type}}#{file[:checksum_value]}")
1645
+ end
1646
+ end
1628
1647
  end
1629
1648
  end
1630
1649
 
@@ -1657,6 +1676,13 @@ describe Puppet::Type.type(:file) do
1657
1676
  file[:checksum_value] = ''
1658
1677
  expect { file.validate }.to_not raise_error
1659
1678
  end
1679
+
1680
+ it 'writes a file' do
1681
+ file[:ensure] = :file
1682
+ file.property(:ensure).sync
1683
+
1684
+ expect(file.parameter(:checksum).sum_file(file[:path])).to eq('{none}')
1685
+ end
1660
1686
  end
1661
1687
 
1662
1688
  describe "when auditing" do