puppet 6.11.1-x86-mingw32 → 6.16.0-x86-mingw32

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

Potentially problematic release.


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

Files changed (395) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +3 -8
  3. data/CONTRIBUTING.md +7 -13
  4. data/Gemfile +1 -0
  5. data/Gemfile.lock +39 -36
  6. data/README.md +17 -24
  7. data/ext/build_defaults.yaml +1 -0
  8. data/ext/project_data.yaml +1 -1
  9. data/ext/windows/service/daemon.rb +25 -20
  10. data/lib/puppet.rb +52 -13
  11. data/lib/puppet/agent.rb +20 -14
  12. data/lib/puppet/application/agent.rb +12 -14
  13. data/lib/puppet/application/describe.rb +7 -5
  14. data/lib/puppet/application/device.rb +2 -2
  15. data/lib/puppet/application/filebucket.rb +19 -15
  16. data/lib/puppet/application/plugin.rb +1 -0
  17. data/lib/puppet/application/resource.rb +1 -1
  18. data/lib/puppet/application/ssl.rb +4 -4
  19. data/lib/puppet/concurrent.rb +2 -0
  20. data/lib/puppet/concurrent/lock.rb +16 -0
  21. data/lib/puppet/concurrent/synchronized.rb +15 -0
  22. data/lib/puppet/concurrent/thread_local_singleton.rb +14 -0
  23. data/lib/puppet/configurer.rb +85 -83
  24. data/lib/puppet/configurer/plugin_handler.rb +10 -1
  25. data/lib/puppet/context/trusted_information.rb +14 -8
  26. data/lib/puppet/daemon.rb +13 -27
  27. data/lib/puppet/defaults.rb +158 -40
  28. data/lib/puppet/environments.rb +30 -20
  29. data/lib/puppet/error.rb +9 -1
  30. data/lib/puppet/face/facts.rb +8 -5
  31. data/lib/puppet/face/help.rb +29 -3
  32. data/lib/puppet/face/module/search.rb +5 -0
  33. data/lib/puppet/face/plugin.rb +2 -2
  34. data/lib/puppet/file_serving/http_metadata.rb +1 -1
  35. data/lib/puppet/file_system/file_impl.rb +13 -9
  36. data/lib/puppet/file_system/memory_file.rb +6 -0
  37. data/lib/puppet/file_system/memory_impl.rb +13 -0
  38. data/lib/puppet/file_system/uniquefile.rb +4 -0
  39. data/lib/puppet/file_system/windows.rb +7 -10
  40. data/lib/puppet/forge.rb +3 -3
  41. data/lib/puppet/forge/errors.rb +2 -2
  42. data/lib/puppet/forge/repository.rb +31 -86
  43. data/lib/puppet/functions/call.rb +1 -1
  44. data/lib/puppet/functions/camelcase.rb +2 -2
  45. data/lib/puppet/functions/epp.rb +4 -4
  46. data/lib/puppet/functions/eyaml_lookup_key.rb +13 -8
  47. data/lib/puppet/functions/filter.rb +1 -0
  48. data/lib/puppet/functions/find_file.rb +9 -9
  49. data/lib/puppet/functions/find_template.rb +63 -0
  50. data/lib/puppet/functions/inline_epp.rb +5 -5
  51. data/lib/puppet/functions/reduce.rb +2 -4
  52. data/lib/puppet/http.rb +7 -0
  53. data/lib/puppet/http/client.rb +341 -54
  54. data/lib/puppet/http/errors.rb +2 -0
  55. data/lib/puppet/http/external_client.rb +90 -0
  56. data/lib/puppet/http/redirector.rb +34 -0
  57. data/lib/puppet/http/resolver.rb +57 -1
  58. data/lib/puppet/http/resolver/server_list.rb +98 -0
  59. data/lib/puppet/http/resolver/settings.rb +23 -2
  60. data/lib/puppet/http/resolver/srv.rb +36 -4
  61. data/lib/puppet/http/response.rb +68 -1
  62. data/lib/puppet/http/retry_after_handler.rb +39 -0
  63. data/lib/puppet/http/service.rb +179 -3
  64. data/lib/puppet/http/service/ca.rb +84 -21
  65. data/lib/puppet/http/service/compiler.rb +319 -0
  66. data/lib/puppet/http/service/file_server.rb +206 -0
  67. data/lib/puppet/http/service/report.rb +66 -0
  68. data/lib/puppet/http/session.rb +106 -31
  69. data/lib/puppet/indirector/catalog/compiler.rb +10 -0
  70. data/lib/puppet/indirector/catalog/rest.rb +34 -0
  71. data/lib/puppet/indirector/facts/rest.rb +42 -0
  72. data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
  73. data/lib/puppet/indirector/file_bucket_file/rest.rb +48 -0
  74. data/lib/puppet/indirector/file_content/http.rb +5 -0
  75. data/lib/puppet/indirector/file_content/rest.rb +30 -0
  76. data/lib/puppet/indirector/file_metadata/http.rb +4 -4
  77. data/lib/puppet/indirector/file_metadata/rest.rb +52 -0
  78. data/lib/puppet/indirector/json.rb +1 -1
  79. data/lib/puppet/indirector/msgpack.rb +1 -1
  80. data/lib/puppet/indirector/node/rest.rb +24 -0
  81. data/lib/puppet/indirector/report/rest.rb +19 -0
  82. data/lib/puppet/indirector/report/yaml.rb +23 -0
  83. data/lib/puppet/indirector/rest.rb +12 -0
  84. data/lib/puppet/indirector/status/rest.rb +18 -0
  85. data/lib/puppet/loaders.rb +6 -0
  86. data/lib/puppet/metatype/manager.rb +80 -80
  87. data/lib/puppet/network/http/base_pool.rb +19 -1
  88. data/lib/puppet/network/http/compression.rb +7 -0
  89. data/lib/puppet/network/http/connection.rb +6 -0
  90. data/lib/puppet/network/http/connection_adapter.rb +182 -0
  91. data/lib/puppet/network/http/nocache_pool.rb +2 -0
  92. data/lib/puppet/network/http/pool.rb +13 -6
  93. data/lib/puppet/network/http_pool.rb +2 -1
  94. data/lib/puppet/node/environment.rb +24 -8
  95. data/lib/puppet/pal/catalog_compiler.rb +5 -0
  96. data/lib/puppet/pal/pal_impl.rb +9 -29
  97. data/lib/puppet/parser/ast/pops_bridge.rb +6 -11
  98. data/lib/puppet/parser/compiler.rb +42 -32
  99. data/lib/puppet/parser/functions.rb +18 -13
  100. data/lib/puppet/parser/functions/epp.rb +3 -3
  101. data/lib/puppet/parser/functions/filter.rb +1 -0
  102. data/lib/puppet/parser/functions/inline_epp.rb +5 -5
  103. data/lib/puppet/pops/evaluator/access_operator.rb +2 -2
  104. data/lib/puppet/pops/evaluator/evaluator_impl.rb +1 -1
  105. data/lib/puppet/pops/evaluator/runtime3_support.rb +1 -1
  106. data/lib/puppet/pops/loader/puppet_plan_instantiator.rb +12 -3
  107. data/lib/puppet/pops/loaders.rb +7 -5
  108. data/lib/puppet/pops/lookup/invocation.rb +10 -3
  109. data/lib/puppet/pops/model/pn_transformer.rb +5 -9
  110. data/lib/puppet/pops/parser/evaluating_parser.rb +8 -11
  111. data/lib/puppet/pops/serialization/json_path.rb +3 -3
  112. data/lib/puppet/pops/time/timespan.rb +3 -5
  113. data/lib/puppet/pops/types/p_object_type_extension.rb +10 -0
  114. data/lib/puppet/pops/types/string_converter.rb +6 -9
  115. data/lib/puppet/pops/types/type_calculator.rb +30 -10
  116. data/lib/puppet/pops/types/type_formatter.rb +9 -11
  117. data/lib/puppet/pops/types/type_parser.rb +3 -3
  118. data/lib/puppet/pops/validation/checker4_0.rb +1 -1
  119. data/lib/puppet/pops/validation/tasks_checker.rb +5 -1
  120. data/lib/puppet/provider/aix_object.rb +4 -2
  121. data/lib/puppet/provider/group/aix.rb +1 -0
  122. data/lib/puppet/provider/group/groupadd.rb +57 -24
  123. data/lib/puppet/provider/group/windows_adsi.rb +3 -3
  124. data/lib/puppet/provider/package/aix.rb +17 -2
  125. data/lib/puppet/provider/package/apt.rb +78 -4
  126. data/lib/puppet/provider/package/dnfmodule.rb +69 -15
  127. data/lib/puppet/provider/package/dpkg.rb +14 -7
  128. data/lib/puppet/provider/package/fink.rb +20 -3
  129. data/lib/puppet/provider/package/gem.rb +41 -7
  130. data/lib/puppet/provider/package/openbsd.rb +13 -1
  131. data/lib/puppet/provider/package/pacman.rb +2 -5
  132. data/lib/puppet/provider/package/pip.rb +143 -48
  133. data/lib/puppet/provider/package/pip3.rb +0 -2
  134. data/lib/puppet/provider/package/pkg.rb +18 -5
  135. data/lib/puppet/provider/package/pkgdmg.rb +1 -1
  136. data/lib/puppet/provider/package/pkgng.rb +16 -4
  137. data/lib/puppet/provider/package/portage.rb +5 -5
  138. data/lib/puppet/provider/package/puppet_gem.rb +6 -2
  139. data/lib/puppet/provider/package/rpm.rb +6 -213
  140. data/lib/puppet/provider/package/yum.rb +108 -24
  141. data/lib/puppet/provider/package/zypper.rb +59 -1
  142. data/lib/puppet/provider/package_targetable.rb +5 -4
  143. data/lib/puppet/provider/service/systemd.rb +23 -5
  144. data/lib/puppet/provider/user/aix.rb +1 -0
  145. data/lib/puppet/provider/user/directoryservice.rb +30 -5
  146. data/lib/puppet/provider/user/hpux.rb +1 -1
  147. data/lib/puppet/provider/user/useradd.rb +11 -8
  148. data/lib/puppet/reports/http.rb +13 -9
  149. data/lib/puppet/reports/store.rb +1 -1
  150. data/lib/puppet/resource/type_collection.rb +20 -16
  151. data/lib/puppet/runtime.rb +32 -1
  152. data/lib/puppet/settings.rb +4 -0
  153. data/lib/puppet/settings/http_extra_headers_setting.rb +25 -0
  154. data/lib/puppet/ssl.rb +1 -0
  155. data/lib/puppet/ssl/certificate.rb +2 -1
  156. data/lib/puppet/ssl/host.rb +4 -4
  157. data/lib/puppet/ssl/oids.rb +1 -0
  158. data/lib/puppet/ssl/ssl_provider.rb +20 -0
  159. data/lib/puppet/ssl/state_machine.rb +81 -35
  160. data/lib/puppet/ssl/verifier_adapter.rb +9 -1
  161. data/lib/puppet/test/test_helper.rb +7 -1
  162. data/lib/puppet/transaction.rb +33 -11
  163. data/lib/puppet/transaction/report.rb +2 -2
  164. data/lib/puppet/transaction/resource_harness.rb +1 -1
  165. data/lib/puppet/type.rb +7 -2
  166. data/lib/puppet/type/file.rb +13 -0
  167. data/lib/puppet/type/file/data_sync.rb +5 -1
  168. data/lib/puppet/type/file/source.rb +49 -58
  169. data/lib/puppet/type/group.rb +5 -4
  170. data/lib/puppet/type/package.rb +102 -10
  171. data/lib/puppet/type/service.rb +6 -8
  172. data/lib/puppet/type/user.rb +6 -30
  173. data/lib/puppet/util.rb +34 -11
  174. data/lib/puppet/util/at_fork.rb +1 -1
  175. data/lib/puppet/util/autoload.rb +4 -18
  176. data/lib/puppet/util/instance_loader.rb +14 -10
  177. data/lib/puppet/util/log/destinations.rb +2 -11
  178. data/lib/puppet/util/logging.rb +30 -18
  179. data/lib/puppet/util/package/version/debian.rb +175 -0
  180. data/lib/puppet/util/package/version/gem.rb +15 -0
  181. data/lib/puppet/util/package/version/pip.rb +167 -0
  182. data/lib/puppet/util/package/version/range.rb +53 -0
  183. data/lib/puppet/util/package/version/range/eq.rb +14 -0
  184. data/lib/puppet/util/package/version/range/gt.rb +14 -0
  185. data/lib/puppet/util/package/version/range/gt_eq.rb +14 -0
  186. data/lib/puppet/util/package/version/range/lt.rb +14 -0
  187. data/lib/puppet/util/package/version/range/lt_eq.rb +14 -0
  188. data/lib/puppet/util/package/version/range/min_max.rb +21 -0
  189. data/lib/puppet/util/package/version/range/simple.rb +11 -0
  190. data/lib/puppet/util/package/version/rpm.rb +73 -0
  191. data/lib/puppet/util/pidlock.rb +36 -10
  192. data/lib/puppet/util/platform.rb +5 -0
  193. data/lib/puppet/util/plist.rb +6 -0
  194. data/lib/puppet/util/rpm_compare.rb +193 -0
  195. data/lib/puppet/util/storage.rb +0 -1
  196. data/lib/puppet/util/windows/adsi.rb +50 -20
  197. data/lib/puppet/util/windows/process.rb +15 -14
  198. data/lib/puppet/util/windows/security.rb +1 -0
  199. data/lib/puppet/util/windows/sid.rb +3 -3
  200. data/lib/puppet/util/yaml.rb +1 -1
  201. data/lib/puppet/version.rb +1 -1
  202. data/lib/puppet/x509/cert_provider.rb +9 -5
  203. data/locales/puppet.pot +640 -521
  204. data/man/man5/puppet.conf.5 +88 -9
  205. data/man/man8/puppet-agent.8 +6 -6
  206. data/man/man8/puppet-apply.8 +1 -1
  207. data/man/man8/puppet-catalog.8 +1 -1
  208. data/man/man8/puppet-config.8 +1 -1
  209. data/man/man8/puppet-describe.8 +1 -1
  210. data/man/man8/puppet-device.8 +2 -2
  211. data/man/man8/puppet-doc.8 +1 -1
  212. data/man/man8/puppet-epp.8 +1 -1
  213. data/man/man8/puppet-facts.8 +1 -1
  214. data/man/man8/puppet-filebucket.8 +17 -2
  215. data/man/man8/puppet-generate.8 +1 -1
  216. data/man/man8/puppet-help.8 +6 -3
  217. data/man/man8/puppet-key.8 +1 -1
  218. data/man/man8/puppet-lookup.8 +1 -1
  219. data/man/man8/puppet-man.8 +1 -1
  220. data/man/man8/puppet-module.8 +4 -1
  221. data/man/man8/puppet-node.8 +1 -1
  222. data/man/man8/puppet-parser.8 +1 -1
  223. data/man/man8/puppet-plugin.8 +1 -1
  224. data/man/man8/puppet-report.8 +1 -1
  225. data/man/man8/puppet-resource.8 +1 -1
  226. data/man/man8/puppet-script.8 +1 -1
  227. data/man/man8/puppet-ssl.8 +2 -2
  228. data/man/man8/puppet-status.8 +1 -1
  229. data/man/man8/puppet.8 +2 -2
  230. data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +67 -0
  231. data/spec/fixtures/ssl/unknown-127.0.0.1.pem +48 -0
  232. data/spec/fixtures/ssl/unknown-ca-key.pem +67 -0
  233. data/spec/fixtures/ssl/unknown-ca.pem +59 -0
  234. data/spec/fixtures/unit/forge/bacula.json +76 -0
  235. data/spec/fixtures/unit/provider/package/dnfmodule/{dnf-module-list-installed.txt → dnf-module-list.txt} +8 -0
  236. data/spec/fixtures/unit/provider/package/pkgng/pkg.version +2 -0
  237. data/spec/fixtures/unit/provider/package/yum/yum-check-update-subscription-manager.txt +9 -0
  238. data/spec/fixtures/unit/provider/package/zypper/zypper-search-uninstalled.out +13 -0
  239. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services +9 -0
  240. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_fetch_if_not_on_the_local_disk.yml +1 -102
  241. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_not_update_if_content_on_disk_is_up-to-date.yml +1 -106
  242. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_update_if_content_differs_on_disk.yml +1 -106
  243. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_mtime_is_older_on_disk.yml +1 -102
  244. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_no_header_specified.yml +1 -98
  245. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_not_on_the_local_disk.yml +1 -102
  246. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_not_update_if_mtime_is_newer_on_disk.yml +1 -102
  247. data/spec/integration/application/agent_spec.rb +394 -0
  248. data/spec/integration/application/apply_spec.rb +132 -3
  249. data/spec/integration/application/filebucket_spec.rb +190 -0
  250. data/spec/integration/application/plugin_spec.rb +73 -0
  251. data/spec/integration/configurer_spec.rb +26 -7
  252. data/spec/integration/http/client_spec.rb +154 -0
  253. data/spec/integration/indirector/facts/facter_spec.rb +4 -0
  254. data/spec/integration/indirector/report/yaml.rb +83 -0
  255. data/spec/integration/module_tool/forge_spec.rb +51 -0
  256. data/spec/integration/network/http_pool_spec.rb +76 -20
  257. data/spec/integration/node/environment_spec.rb +15 -0
  258. data/spec/integration/util/windows/adsi_spec.rb +6 -1
  259. data/spec/lib/puppet/test_ca.rb +2 -2
  260. data/spec/lib/puppet_spec/https.rb +20 -9
  261. data/spec/lib/puppet_spec/puppetserver.rb +119 -0
  262. data/spec/shared_contexts/https.rb +29 -0
  263. data/spec/spec_helper.rb +6 -2
  264. data/spec/unit/agent_spec.rb +80 -26
  265. data/spec/unit/application/agent_spec.rb +9 -5
  266. data/spec/unit/application/apply_spec.rb +2 -12
  267. data/spec/unit/application/describe_spec.rb +88 -50
  268. data/spec/unit/application/device_spec.rb +2 -2
  269. data/spec/unit/application/filebucket_spec.rb +22 -2
  270. data/spec/unit/application/resource_spec.rb +2 -2
  271. data/spec/unit/concurrent/lock_spec.rb +29 -0
  272. data/spec/unit/configurer/fact_handler_spec.rb +0 -4
  273. data/spec/unit/configurer/plugin_handler_spec.rb +36 -19
  274. data/spec/unit/configurer_spec.rb +400 -406
  275. data/spec/unit/context/trusted_information_spec.rb +17 -0
  276. data/spec/unit/daemon_spec.rb +5 -64
  277. data/spec/unit/defaults_spec.rb +38 -4
  278. data/spec/unit/environments_spec.rb +65 -28
  279. data/spec/unit/face/facts_spec.rb +24 -20
  280. data/spec/unit/face/module/search_spec.rb +17 -0
  281. data/spec/unit/face/plugin_spec.rb +12 -10
  282. data/spec/unit/file_system/uniquefile_spec.rb +11 -0
  283. data/spec/unit/file_system_spec.rb +26 -2
  284. data/spec/unit/forge/errors_spec.rb +1 -1
  285. data/spec/unit/forge/forge_spec.rb +12 -54
  286. data/spec/unit/forge/module_release_spec.rb +19 -6
  287. data/spec/unit/forge/repository_spec.rb +63 -157
  288. data/spec/unit/forge_spec.rb +46 -116
  289. data/spec/unit/functions/find_template_spec.rb +69 -0
  290. data/spec/unit/functions/lookup_spec.rb +13 -0
  291. data/spec/unit/http/client_spec.rb +395 -27
  292. data/spec/unit/http/external_client_spec.rb +201 -0
  293. data/spec/unit/http/resolver_spec.rb +81 -12
  294. data/spec/unit/http/response_spec.rb +69 -0
  295. data/spec/unit/http/service/ca_spec.rb +100 -7
  296. data/spec/unit/http/service/compiler_spec.rb +627 -0
  297. data/spec/unit/http/service/file_server_spec.rb +308 -0
  298. data/spec/unit/http/service/report_spec.rb +118 -0
  299. data/spec/unit/http/service_spec.rb +117 -4
  300. data/spec/unit/http/session_spec.rb +237 -19
  301. data/spec/unit/indirector/catalog/compiler_spec.rb +47 -29
  302. data/spec/unit/indirector/catalog/rest_spec.rb +59 -2
  303. data/spec/unit/indirector/facts/rest_spec.rb +79 -24
  304. data/spec/unit/indirector/file_bucket_file/rest_spec.rb +82 -2
  305. data/spec/unit/indirector/file_content/rest_spec.rb +53 -2
  306. data/spec/unit/indirector/file_metadata/http_spec.rb +167 -0
  307. data/spec/unit/indirector/file_metadata/rest_spec.rb +110 -2
  308. data/spec/unit/indirector/node/rest_spec.rb +57 -2
  309. data/spec/unit/indirector/report/rest_spec.rb +58 -51
  310. data/spec/unit/indirector/resource/ral_spec.rb +7 -8
  311. data/spec/unit/indirector/rest_spec.rb +13 -0
  312. data/spec/unit/indirector/status/rest_spec.rb +43 -2
  313. data/spec/unit/network/http/connection_spec.rb +549 -176
  314. data/spec/unit/network/http/nocache_pool_spec.rb +25 -3
  315. data/spec/unit/network/http/pool_spec.rb +89 -11
  316. data/spec/unit/network/http_pool_spec.rb +63 -57
  317. data/spec/unit/network/http_spec.rb +1 -1
  318. data/spec/unit/node/environment_spec.rb +16 -0
  319. data/spec/unit/node/facts_spec.rb +2 -1
  320. data/spec/unit/node_spec.rb +7 -4
  321. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +8 -3
  322. data/spec/unit/pops/serialization/to_from_hr_spec.rb +6 -1
  323. data/spec/unit/pops/validator/validator_spec.rb +7 -2
  324. data/spec/unit/provider/aix_object_spec.rb +16 -2
  325. data/spec/unit/provider/group/groupadd_spec.rb +181 -56
  326. data/spec/unit/provider/group/windows_adsi_spec.rb +43 -10
  327. data/spec/unit/provider/package/aix_spec.rb +29 -0
  328. data/spec/unit/provider/package/apt_spec.rb +43 -2
  329. data/spec/unit/provider/package/aptitude_spec.rb +1 -0
  330. data/spec/unit/provider/package/dnfmodule_spec.rb +76 -15
  331. data/spec/unit/provider/package/dpkg_spec.rb +28 -6
  332. data/spec/unit/provider/package/gem_spec.rb +40 -0
  333. data/spec/unit/provider/package/openbsd_spec.rb +17 -0
  334. data/spec/unit/provider/package/pacman_spec.rb +6 -21
  335. data/spec/unit/provider/package/pip_spec.rb +68 -19
  336. data/spec/unit/provider/package/pkg_spec.rb +15 -1
  337. data/spec/unit/provider/package/pkgdmg_spec.rb +1 -1
  338. data/spec/unit/provider/package/pkgng_spec.rb +38 -0
  339. data/spec/unit/provider/package/portage_spec.rb +9 -4
  340. data/spec/unit/provider/package/puppet_gem_spec.rb +8 -0
  341. data/spec/unit/provider/package/rpm_spec.rb +0 -212
  342. data/spec/unit/provider/package/yum_spec.rb +292 -0
  343. data/spec/unit/provider/package/zypper_spec.rb +84 -0
  344. data/spec/unit/provider/package_targetable_spec.rb +60 -0
  345. data/spec/unit/provider/service/init_spec.rb +1 -0
  346. data/spec/unit/provider/service/openbsd_spec.rb +9 -0
  347. data/spec/unit/provider/service/openwrt_spec.rb +1 -0
  348. data/spec/unit/provider/service/redhat_spec.rb +9 -0
  349. data/spec/unit/provider/service/systemd_spec.rb +92 -12
  350. data/spec/unit/provider/user/directoryservice_spec.rb +41 -0
  351. data/spec/unit/provider/user/hpux_spec.rb +2 -2
  352. data/spec/unit/provider/user/useradd_spec.rb +21 -8
  353. data/spec/unit/provider/user/windows_adsi_spec.rb +3 -3
  354. data/spec/unit/puppet_pal_2pec.rb +0 -26
  355. data/spec/unit/puppet_pal_catalog_spec.rb +46 -0
  356. data/spec/unit/puppet_spec.rb +47 -0
  357. data/spec/unit/reports/http_spec.rb +70 -52
  358. data/spec/unit/settings/autosign_setting_spec.rb +1 -1
  359. data/spec/unit/settings/http_extra_headers_spec.rb +64 -0
  360. data/spec/unit/ssl/certificate_spec.rb +7 -0
  361. data/spec/unit/ssl/host_spec.rb +4 -2
  362. data/spec/unit/ssl/oids_spec.rb +1 -0
  363. data/spec/unit/ssl/ssl_provider_spec.rb +71 -0
  364. data/spec/unit/ssl/state_machine_spec.rb +99 -13
  365. data/spec/unit/transaction/persistence_spec.rb +1 -10
  366. data/spec/unit/transaction/report_spec.rb +4 -0
  367. data/spec/unit/transaction_spec.rb +45 -1
  368. data/spec/unit/type/file/content_spec.rb +9 -3
  369. data/spec/unit/type/file/ensure_spec.rb +1 -2
  370. data/spec/unit/type/file/source_spec.rb +86 -35
  371. data/spec/unit/type/package_spec.rb +8 -0
  372. data/spec/unit/type/service_spec.rb +9 -8
  373. data/spec/unit/type/user_spec.rb +1 -2
  374. data/spec/unit/util/at_fork_spec.rb +3 -2
  375. data/spec/unit/util/autoload_spec.rb +2 -1
  376. data/spec/unit/util/log/destinations_spec.rb +1 -29
  377. data/spec/unit/util/log_spec.rb +0 -138
  378. data/spec/unit/util/logging_spec.rb +200 -0
  379. data/spec/unit/util/package/version/debian_spec.rb +83 -0
  380. data/spec/unit/util/package/version/pip_spec.rb +464 -0
  381. data/spec/unit/util/package/version/range_spec.rb +175 -0
  382. data/spec/unit/util/package/version/rpm_spec.rb +121 -0
  383. data/spec/unit/util/pidlock_spec.rb +112 -42
  384. data/spec/unit/util/plist_spec.rb +20 -0
  385. data/spec/unit/util/rpm_compare_spec.rb +196 -0
  386. data/spec/unit/util/storage_spec.rb +1 -8
  387. data/spec/unit/util/windows/adsi_spec.rb +55 -4
  388. data/spec/unit/util/windows/sid_spec.rb +2 -2
  389. data/spec/unit/x509/cert_provider_spec.rb +24 -4
  390. data/tasks/generate_cert_fixtures.rake +15 -1
  391. data/tasks/manpages.rake +6 -35
  392. metadata +92 -12
  393. data/COMMITTERS.md +0 -244
  394. data/spec/integration/faces/plugin_spec.rb +0 -61
  395. data/spec/lib/puppet_spec/validators.rb +0 -37
@@ -30,6 +30,7 @@ class Puppet::Settings
30
30
  require 'puppet/settings/value_translator'
31
31
  require 'puppet/settings/environment_conf'
32
32
  require 'puppet/settings/server_list_setting'
33
+ require 'puppet/settings/http_extra_headers_setting'
33
34
  require 'puppet/settings/certificate_revocation_setting'
34
35
 
35
36
  # local reference for convenience
@@ -727,6 +728,7 @@ class Puppet::Settings
727
728
  :priority => PrioritySetting,
728
729
  :autosign => AutosignSetting,
729
730
  :server_list => ServerListSetting,
731
+ :http_extra_headers => HttpExtraHeadersSetting,
730
732
  :certificate_revocation => CertificateRevocationSetting
731
733
  }
732
734
 
@@ -1239,6 +1241,8 @@ Generated on #{Time.now}.
1239
1241
  configured_environment = self[:environment]
1240
1242
  if configured_environment == "production" && envdir && Puppet::FileSystem.exist?(envdir)
1241
1243
  configured_environment_path = File.join(envdir, configured_environment)
1244
+ # If configured_environment_path is a symlink, assume the source path is being managed
1245
+ # elsewhere, so don't do any of this configuration
1242
1246
  if !Puppet::FileSystem.symlink?(configured_environment_path)
1243
1247
  parameters = { :ensure => 'directory' }
1244
1248
  unless Puppet::FileSystem.exist?(configured_environment_path)
@@ -0,0 +1,25 @@
1
+ class Puppet::Settings::HttpExtraHeadersSetting < Puppet::Settings::BaseSetting
2
+
3
+ def type
4
+ :http_extra_headers
5
+ end
6
+
7
+ def munge(headers)
8
+ return headers if headers.is_a?(Hash)
9
+
10
+ headers = headers.split(/\s*,\s*/) if headers.is_a?(String)
11
+
12
+ raise ArgumentError, _("Expected an Array, String, or Hash, got a %{klass}") % { klass: headers.class } unless headers.is_a?(Array)
13
+
14
+ headers.map! { |header|
15
+ case header
16
+ when String
17
+ header.split(':')
18
+ when Array
19
+ header
20
+ else
21
+ raise ArgumentError, _("Expected an Array or String, got a %{klass}") % { klass: header.class }
22
+ end
23
+ }
24
+ end
25
+ end
@@ -2,6 +2,7 @@
2
2
  require 'puppet'
3
3
  require 'puppet/ssl/openssl_loader'
4
4
 
5
+ # @api private
5
6
  module Puppet::SSL # :nodoc:
6
7
  CA_NAME = "ca".freeze
7
8
  require 'puppet/ssl/host'
@@ -56,7 +56,8 @@ DOC
56
56
  def custom_extensions
57
57
  custom_exts = content.extensions.select do |ext|
58
58
  Puppet::SSL::Oids.subtree_of?('ppRegCertExt', ext.oid) or
59
- Puppet::SSL::Oids.subtree_of?('ppPrivCertExt', ext.oid)
59
+ Puppet::SSL::Oids.subtree_of?('ppPrivCertExt', ext.oid) or
60
+ Puppet::SSL::Oids.subtree_of?('ppAuthCertExt', ext.oid)
60
61
  end
61
62
 
62
63
  custom_exts.map do |ext|
@@ -22,9 +22,9 @@ class Puppet::SSL::Host
22
22
 
23
23
  attr_writer :key, :certificate, :certificate_request, :crl_usage
24
24
 
25
- def self.localhost
25
+ def self.localhost(suppress_warning = false)
26
26
  return @localhost if @localhost
27
- @localhost = new
27
+ @localhost = new(nil, false, suppress_warning)
28
28
  @localhost.generate unless @localhost.certificate
29
29
  @localhost.key
30
30
  @localhost
@@ -225,14 +225,14 @@ ERROR_STRING
225
225
  end
226
226
  private :validate_csr_with_key
227
227
 
228
- def initialize(name = nil, device = false)
228
+ def initialize(name = nil, device = false, suppress_warning = false)
229
229
  @name = (name || Puppet[:certname]).downcase
230
230
  @device = device
231
231
  Puppet::SSL::Base.validate_certname(@name)
232
232
  @key = @certificate = @certificate_request = nil
233
233
  @crl_usage = Puppet.settings[:certificate_revocation]
234
234
  @crl_path = Puppet.settings[:hostcrl]
235
- Puppet.deprecation_warning(_("Puppet::SSL::Host is deprecated and will be removed in a future release of Puppet."));
235
+ Puppet.deprecation_warning(_("Puppet::SSL::Host is deprecated and will be removed in a future release of Puppet.")) unless suppress_warning
236
236
  end
237
237
 
238
238
  # Extract the public key from the private key.
@@ -61,6 +61,7 @@ module Puppet::SSL::Oids
61
61
  ["1.3.6.1.4.1.34380.1.1.23", 'pp_cloudplatform', 'Puppet Node Cloud Platform Name'],
62
62
  ["1.3.6.1.4.1.34380.1.1.24", 'pp_apptier', 'Puppet Node Application Tier'],
63
63
  ["1.3.6.1.4.1.34380.1.1.25", 'pp_hostname', 'Puppet Node Hostname'],
64
+ ["1.3.6.1.4.1.34380.1.1.26", 'pp_owner', 'Puppet Node Owner'],
64
65
 
65
66
  ["1.3.6.1.4.1.34380.1.2", 'ppPrivCertExt', 'Puppet Private Certificate Extension'],
66
67
 
@@ -36,6 +36,26 @@ class Puppet::SSL::SSLProvider
36
36
  Puppet::SSL::SSLContext.new(store: store, cacerts: cacerts, crls: crls, revocation: revocation).freeze
37
37
  end
38
38
 
39
+ # Create an `SSLContext` using the trusted `cacerts` and any certs in OpenSSL's
40
+ # default verify path locations. When running puppet as a gem, the location is
41
+ # system dependent. When running puppet from puppet-agent packages, the location
42
+ # refers to the cacerts bundle in the puppet-agent package.
43
+ #
44
+ # Connections made from the returned context will authenticate the server,
45
+ # i.e. `VERIFY_PEER`, but will not use a client certificate and will not
46
+ # perform revocation checking.
47
+ #
48
+ # @param cacerts [Array<OpenSSL::X509::Certificate>] Array of trusted CA certs
49
+ # @return [Puppet::SSL::SSLContext] A context to use to create connections
50
+ # @raise (see #create_context)
51
+ # @api private
52
+ def create_system_context(cacerts:)
53
+ store = create_x509_store(cacerts, [], false)
54
+ store.set_default_paths
55
+
56
+ Puppet::SSL::SSLContext.new(store: store, cacerts: cacerts, crls: [], revocation: false).freeze
57
+ end
58
+
39
59
  # Create an `SSLContext` using the trusted `cacerts`, `crls`, `private_key`,
40
60
  # `client_cert`, and `revocation` mode. Connections made from the returned
41
61
  # context will be mutually authenticated.
@@ -45,7 +45,7 @@ class Puppet::SSL::StateMachine
45
45
  next_ctx = @ssl_provider.create_root_context(cacerts: cacerts, revocation: false)
46
46
  else
47
47
  route = @machine.session.route_to(:ca, ssl_context: @ssl_context)
48
- pem = route.get_certificate(Puppet::SSL::CA_NAME, ssl_context: @ssl_context)
48
+ _, pem = route.get_certificate(Puppet::SSL::CA_NAME, ssl_context: @ssl_context)
49
49
  if @machine.ca_fingerprint
50
50
  actual_digest = Puppet::SSL::Digest.new(@machine.digest, pem).to_hex
51
51
  expected_digest = @machine.ca_fingerprint.scan(/../).join(':').upcase
@@ -146,7 +146,7 @@ class Puppet::SSL::StateMachine
146
146
 
147
147
  def download_crl(ssl_ctx, last_update)
148
148
  route = @machine.session.route_to(:ca, ssl_context: ssl_ctx)
149
- pem = route.get_certificate_revocation_list(if_modified_since: last_update, ssl_context: ssl_ctx)
149
+ _, pem = route.get_certificate_revocation_list(if_modified_since: last_update, ssl_context: ssl_ctx)
150
150
  crls = @cert_provider.load_crls_from_pem(pem)
151
151
  # verify crls before saving
152
152
  next_ctx = @ssl_provider.create_root_context(cacerts: ssl_ctx[:cacerts], crls: crls)
@@ -234,7 +234,7 @@ class Puppet::SSL::StateMachine
234
234
 
235
235
  route = @machine.session.route_to(:ca, ssl_context: @ssl_context)
236
236
  cert = OpenSSL::X509::Certificate.new(
237
- route.get_certificate(Puppet[:certname], ssl_context: @ssl_context)
237
+ route.get_certificate(Puppet[:certname], ssl_context: @ssl_context)[1]
238
238
  )
239
239
  Puppet.info _("Downloaded certificate for %{name} from %{url}") % { name: Puppet[:certname], url: route.url }
240
240
  # verify client cert before saving
@@ -278,16 +278,55 @@ class Puppet::SSL::StateMachine
278
278
  else
279
279
  Puppet.info(_("Will try again in %{time} seconds.") % {time: time})
280
280
 
281
+ # close persistent connections and session state before sleeping
282
+ Puppet.runtime[:http].close
283
+ @machine.session = Puppet.runtime[:http].create_session
284
+
285
+ @machine.unlock
281
286
  Kernel.sleep(time)
287
+ NeedLock.new(@machine)
288
+ end
289
+ end
290
+ end
282
291
 
292
+ # Acquire the ssl lock or return LockFailure causing us to exit.
293
+ #
294
+ class NeedLock < SSLState
295
+ def initialize(machine)
296
+ super(machine, nil)
297
+ end
298
+
299
+ def next_state
300
+ if @machine.lock
283
301
  # our ssl directory may have been cleaned while we were
284
302
  # sleeping, start over from the top
285
- @machine.session = Puppet.runtime['http'].create_session
286
303
  NeedCACerts.new(@machine)
304
+ elsif @machine.waitforlock < 1
305
+ LockFailure.new(@machine, _("Another puppet instance is already running and the waitforlock setting is set to 0; exiting"))
306
+ elsif Time.now.to_i >= @machine.waitlock_deadline
307
+ LockFailure.new(@machine, _("Another puppet instance is already running and the maxwaitforlock timeout has been exceeded; exiting"))
308
+ else
309
+ Puppet.info _("Another puppet instance is already running; waiting for it to finish")
310
+ Puppet.info _("Will try again in %{time} seconds.") % {time: @machine.waitforlock}
311
+ Kernel.sleep @machine.waitforlock
312
+
313
+ # try again
314
+ self
287
315
  end
288
316
  end
289
317
  end
290
318
 
319
+ # We failed to acquire the lock, so exit
320
+ #
321
+ class LockFailure < SSLState
322
+ attr_reader :message
323
+
324
+ def initialize(machine, message)
325
+ super(machine, nil)
326
+ @message = message
327
+ end
328
+ end
329
+
291
330
  # We cannot make progress due to an error.
292
331
  #
293
332
  class Error < SSLState
@@ -310,7 +349,7 @@ class Puppet::SSL::StateMachine
310
349
  #
311
350
  class Done < SSLState; end
312
351
 
313
- attr_reader :waitforcert, :wait_deadline, :cert_provider, :ssl_provider, :ca_fingerprint, :digest
352
+ attr_reader :waitforcert, :wait_deadline, :waitforlock, :waitlock_deadline, :cert_provider, :ssl_provider, :ca_fingerprint, :digest
314
353
  attr_accessor :session
315
354
 
316
355
  # Construct a state machine to manage the SSL initialization process. By
@@ -323,7 +362,12 @@ class Puppet::SSL::StateMachine
323
362
  # then then state machine will exit instead of wait.
324
363
  #
325
364
  # @param waitforcert [Integer] how many seconds to wait between attempts
326
- # @param maxwiatforcert [Integer] maximum amount of second
365
+ # @param maxwaitforcert [Integer] maximum amount of seconds to wait for the
366
+ # server to sign the certificate request
367
+ # @param waitforlock [Integer] how many seconds to wait between attempts for
368
+ # acquiring the ssl lock
369
+ # @param maxwaitforlock [Integer] maximum amount of seconds to wait for an
370
+ # already running process to release the ssl lock
327
371
  # @param onetime [Boolean] whether to run onetime
328
372
  # @param lockfile [Puppet::Util::Pidlock] lockfile to protect against
329
373
  # concurrent modification by multiple processes
@@ -336,6 +380,8 @@ class Puppet::SSL::StateMachine
336
380
  # downloaded CA bundle
337
381
  def initialize(waitforcert: Puppet[:waitforcert],
338
382
  maxwaitforcert: Puppet[:maxwaitforcert],
383
+ waitforlock: Puppet[:waitforlock],
384
+ maxwaitforlock: Puppet[:maxwaitforlock],
339
385
  onetime: Puppet[:onetime],
340
386
  cert_provider: Puppet::X509::CertProvider.new,
341
387
  ssl_provider: Puppet::SSL::SSLProvider.new,
@@ -344,13 +390,15 @@ class Puppet::SSL::StateMachine
344
390
  ca_fingerprint: Puppet[:ca_fingerprint])
345
391
  @waitforcert = waitforcert
346
392
  @wait_deadline = Time.now.to_i + maxwaitforcert
393
+ @waitforlock = waitforlock
394
+ @waitlock_deadline = Time.now.to_i + maxwaitforlock
347
395
  @onetime = onetime
348
396
  @cert_provider = cert_provider
349
397
  @ssl_provider = ssl_provider
350
398
  @lockfile = lockfile
351
399
  @digest = digest
352
400
  @ca_fingerprint = ca_fingerprint
353
- @session = Puppet.runtime['http'].create_session
401
+ @session = Puppet.runtime[:http].create_session
354
402
  end
355
403
 
356
404
  # Run the state machine for CA certs and CRLs.
@@ -358,7 +406,7 @@ class Puppet::SSL::StateMachine
358
406
  # @return [Puppet::SSL::SSLContext] initialized SSLContext
359
407
  # @raise [Puppet::Error] If we fail to generate an SSLContext
360
408
  def ensure_ca_certificates
361
- final_state = run_machine(NeedCACerts.new(self), NeedKey)
409
+ final_state = run_machine(NeedLock.new(self), NeedKey)
362
410
  final_state.ssl_context
363
411
  end
364
412
 
@@ -367,7 +415,7 @@ class Puppet::SSL::StateMachine
367
415
  # @return [Puppet::SSL::SSLContext] initialized SSLContext
368
416
  # @raise [Puppet::Error] If we fail to generate an SSLContext
369
417
  def ensure_client_certificate
370
- final_state = run_machine(NeedCACerts.new(self), Done)
418
+ final_state = run_machine(NeedLock.new(self), Done)
371
419
  ssl_context = final_state.ssl_context
372
420
 
373
421
  if Puppet::Util::Log.sendlevel?(:debug)
@@ -386,40 +434,38 @@ class Puppet::SSL::StateMachine
386
434
  ssl_context
387
435
  end
388
436
 
437
+ def lock
438
+ @lockfile.lock
439
+ end
440
+
441
+ def unlock
442
+ @lockfile.unlock
443
+ end
444
+
389
445
  private
390
446
 
391
447
  def run_machine(state, stop)
392
- with_lock do
393
- loop do
394
- state = run_step(state)
395
-
396
- case state
397
- when stop
398
- break
399
- when Error
400
- if @onetime
401
- Puppet.log_exception(state.error)
402
- raise state.error
403
- end
404
- else
405
- # fall through
448
+ loop do
449
+ state = run_step(state)
450
+
451
+ case state
452
+ when stop
453
+ break
454
+ when LockFailure
455
+ raise Puppet::Error, state.message
456
+ when Error
457
+ if @onetime
458
+ Puppet.log_exception(state.error)
459
+ raise state.error
406
460
  end
461
+ else
462
+ # fall through
407
463
  end
408
464
  end
409
465
 
410
466
  state
411
- end
412
-
413
- def with_lock
414
- if @lockfile.lock
415
- begin
416
- yield
417
- ensure
418
- @lockfile.unlock
419
- end
420
- else
421
- raise Puppet::Error, _('Another puppet instance is already running; exiting')
422
- end
467
+ ensure
468
+ @lockfile.unlock if @lockfile.locked?
423
469
  end
424
470
 
425
471
  def run_step(state)
@@ -6,10 +6,18 @@
6
6
  # loaded above.
7
7
  #
8
8
  class Puppet::SSL::VerifierAdapter
9
- attr_reader :validator
9
+ attr_reader :validator, :ssl_context
10
10
 
11
11
  def initialize(validator)
12
12
  @validator = validator
13
+
14
+ if validator.is_a?(Puppet::SSL::Validator::NoValidator)
15
+ ssl = Puppet::SSL::SSLProvider.new
16
+ @ssl_context = ssl.create_insecure_context
17
+ else
18
+ # nil means use the default SSLContext
19
+ @ssl_context = nil
20
+ end
13
21
  end
14
22
 
15
23
  # Return true if `self` is reusable with `verifier` meaning they
@@ -136,10 +136,12 @@ module Puppet::Test
136
136
  {
137
137
  trusted_information:
138
138
  Puppet::Context::TrustedInformation.new('local', 'testing', {}, { "trusted_testhelper" => true }),
139
- ssl_context: Puppet::SSL::SSLContext.new(cacerts: []).freeze
139
+ ssl_context: Puppet::SSL::SSLContext.new(cacerts: []).freeze,
140
+ http_session: proc { Puppet.runtime[:http].create_session }
140
141
  },
141
142
  "Context for specs")
142
143
 
144
+ Puppet.runtime.clear
143
145
  Puppet::Parser::Functions.reset
144
146
  Puppet::Application.clear!
145
147
  Puppet::Util::Profiler.clear
@@ -147,6 +149,10 @@ module Puppet::Test
147
149
  Puppet::SSL::Host.reset
148
150
  Puppet::Rest::Routes.clear
149
151
 
152
+ Puppet::Node::Facts.indirection.terminus_class = :memory
153
+ facts = Puppet::Node::Facts.new(Puppet[:node_name_value])
154
+ Puppet::Node::Facts.indirection.save(facts)
155
+
150
156
  Puppet.clear_deprecation_warnings
151
157
  end
152
158
 
@@ -57,7 +57,11 @@ class Puppet::Transaction
57
57
 
58
58
  @prefetch_failed_providers = Hash.new { |h,k| h[k] = {} }
59
59
 
60
+ # With merge_dependency_warnings, notify and warn about class dependency failures ... just once per class. TJK 2019-09-09
61
+ @merge_dependency_warnings = Puppet[:merge_dependency_warnings]
60
62
  @failed_dependencies_already_notified = Set.new()
63
+ @failed_class_dependencies_already_notified = Set.new()
64
+ @failed_class_dependencies_already_warned = Set.new()
61
65
  end
62
66
 
63
67
  # Invoke the pre_run_check hook in every resource in the catalog.
@@ -291,15 +295,25 @@ class Puppet::Transaction
291
295
  # explosion of edges, we also ended up reporting failures for containers
292
296
  # like class and stage. This is undesirable; while just skipping the
293
297
  # output isn't perfect, it is RC-safe. --daniel 2011-06-07
294
- suppress_report = (resource.class == Puppet::Type.type(:whit))
295
-
298
+ is_puppet_class = resource.class == Puppet::Type.type(:whit)
299
+ # With merge_dependency_warnings, notify about class dependency failures ... just once per class. TJK 2019-09-09
296
300
  s = resource_status(resource)
297
301
  if s && s.dependency_failed?
298
- # See above. --daniel 2011-06-06
299
- unless suppress_report then
300
- s.failed_dependencies.find_all { |d| !(@failed_dependencies_already_notified.include?(d.ref)) }.each do |dep|
301
- resource.notice _("Dependency %{dep} has failures: %{status}") % { dep: dep, status: resource_status(dep).failed }
302
- @failed_dependencies_already_notified.add(dep.ref)
302
+ if @merge_dependency_warnings && is_puppet_class
303
+ # Notes: Puppet::Resource::Status.failed_dependencies() is an Array of Puppet::Resource(s) and
304
+ # Puppet::Resource.ref() calls Puppet::Resource.to_s() which is: "#{type}[#{title}]" and
305
+ # Puppet::Resource.resource_status(resource) calls Puppet::Resource.to_s()
306
+ class_dependencies_to_be_notified = (s.failed_dependencies.map(&:ref) - @failed_class_dependencies_already_notified.to_a)
307
+ class_dependencies_to_be_notified.each do |dep_ref|
308
+ resource.notice _("Class dependency %{dep} has failures: %{status}") % { dep: dep_ref, status: resource_status(dep_ref).failed }
309
+ end
310
+ @failed_class_dependencies_already_notified.merge(class_dependencies_to_be_notified)
311
+ else
312
+ unless @merge_dependency_warnings || is_puppet_class
313
+ s.failed_dependencies.find_all { |d| !(@failed_dependencies_already_notified.include?(d.ref)) }.each do |dep|
314
+ resource.notice _("Dependency %{dep} has failures: %{status}") % { dep: dep, status: resource_status(dep).failed }
315
+ @failed_dependencies_already_notified.add(dep.ref)
316
+ end
303
317
  end
304
318
  end
305
319
  end
@@ -399,11 +413,19 @@ class Puppet::Transaction
399
413
  # explosion of edges, we also ended up reporting failures for containers
400
414
  # like class and stage. This is undesirable; while just skipping the
401
415
  # output isn't perfect, it is RC-safe. --daniel 2011-06-07
402
- unless resource.class == Puppet::Type.type(:whit) then
403
- resource.warning _("Skipping because of failed dependencies")
416
+ # With merge_dependency_warnings, warn about class dependency failures ... just once per class. TJK 2019-09-09
417
+ unless resource.class == Puppet::Type.type(:whit)
418
+ if @merge_dependency_warnings && resource.parent && failed_dependencies?(resource.parent)
419
+ ps = resource_status(resource.parent)
420
+ ps.failed_dependencies.find_all { |d| !(@failed_class_dependencies_already_warned.include?(d.ref)) }.each do |dep|
421
+ resource.parent.warning _("Skipping resources in class because of failed class dependencies")
422
+ @failed_class_dependencies_already_warned.add(dep.ref)
423
+ end
424
+ else
425
+ resource.warning _("Skipping because of failed dependencies")
426
+ end
404
427
  end
405
- elsif resource_status(resource).failed? &&
406
- @prefetch_failed_providers[resource.type][resource.provider.class.name]
428
+ elsif resource_status(resource).failed? && @prefetch_failed_providers[resource.type][resource.provider.class.name]
407
429
  #Do not try to evaluate a resource with a known failed provider
408
430
  resource.warning _("Skipping because provider prefetch failed")
409
431
  elsif resource.virtual?