puppet 6.12.0-universal-darwin → 6.17.0-universal-darwin

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
@@ -24,7 +24,7 @@ Puppet::Type.type(:group).provide :windows_adsi do
24
24
  # since the default array_matching comparison is not commutative
25
25
 
26
26
  # dupes automatically weeded out when hashes built
27
- current_members = Puppet::Util::Windows::ADSI::Group.name_sid_hash(current)
27
+ current_members = Puppet::Util::Windows::ADSI::Group.name_sid_hash(current, true)
28
28
  specified_members = Puppet::Util::Windows::ADSI::Group.name_sid_hash(should)
29
29
 
30
30
  current_sids = current_members.keys.to_a
@@ -52,7 +52,7 @@ Puppet::Type.type(:group).provide :windows_adsi do
52
52
  account = sid.account
53
53
  end
54
54
  resource.debug("#{sid.domain}\\#{account} (#{sid.sid})")
55
- "#{sid.domain}\\#{account}"
55
+ sid.domain ? "#{sid.domain}\\#{account}" : account
56
56
  end
57
57
  return users.join(',')
58
58
  end
@@ -66,7 +66,7 @@ Puppet::Type.type(:group).provide :windows_adsi do
66
66
  end
67
67
 
68
68
  def members
69
- @members ||= Puppet::Util::Windows::ADSI::Group.name_sid_hash(group.members)
69
+ @members ||= Puppet::Util::Windows::ADSI::Group.name_sid_hash(group.members, true)
70
70
 
71
71
  # @members.keys returns an array of SIDs. We need to convert those SIDs into
72
72
  # names so that `puppet resource` prints the right output.
@@ -29,6 +29,15 @@ Puppet::Type.type(:package).provide :aix, :parent => Puppet::Provider::Package d
29
29
 
30
30
  attr_accessor :latest_info
31
31
 
32
+ STATE_CODE = {
33
+ 'A' => :applied,
34
+ 'B' => :broken,
35
+ 'C' => :committed,
36
+ 'E' => :efix_locked,
37
+ 'O' => :obsolete,
38
+ '?' => :inconsistent,
39
+ }.freeze
40
+
32
41
  def self.srclistcmd(source)
33
42
  [ command(:installp), "-L", "-d", source ]
34
43
  end
@@ -97,6 +106,11 @@ Puppet::Type.type(:package).provide :aix, :parent => Puppet::Provider::Package d
97
106
  if output =~ /^#{Regexp.escape(@resource[:name])}\s+.*\s+Already superseded by.*$/
98
107
  self.fail _("aix package provider is unable to downgrade packages")
99
108
  end
109
+
110
+ pkg_info = query
111
+ if pkg_info && [:broken, :inconsistent].include?(pkg_info[:status])
112
+ self.fail _("Package '%{name}' is in a %{status} state and requires manual intervention") % { name: @resource[:name], status: pkg_info[:status] }
113
+ end
100
114
  end
101
115
 
102
116
  def self.pkglist(hash = {})
@@ -108,8 +122,9 @@ Puppet::Type.type(:package).provide :aix, :parent => Puppet::Provider::Package d
108
122
  end
109
123
 
110
124
  begin
111
- list = execute(cmd).scan(/^[^#][^:]*:([^:]*):([^:]*)/).collect { |n,e|
112
- { :name => n, :ensure => e, :provider => self.name }
125
+ list = execute(cmd).scan(/^[^#][^:]*:([^:]*):([^:]*):[^:]*:[^:]*:([^:])/).collect { |n,e,s|
126
+ e = :absent if [:broken, :inconsistent].include?(STATE_CODE[s])
127
+ { :name => n, :ensure => e, :status => STATE_CODE[s], :provider => self.name }
113
128
  }
114
129
  rescue Puppet::ExecutionFailure => detail
115
130
  if hash[:pkgname]
@@ -1,7 +1,11 @@
1
+ require 'puppet/util/package/version/range'
2
+ require 'puppet/util/package/version/debian'
3
+
1
4
  Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
2
5
  # Provide sorting functionality
3
6
  include Puppet::Util::Package
4
-
7
+ DebianVersion = Puppet::Util::Package::Version::Debian
8
+ VersionRange = Puppet::Util::Package::Version::Range
5
9
  desc "Package management via `apt-get`.
6
10
 
7
11
  This provider supports the `install_options` attribute, which allows command-line flags to be passed to apt-get.
@@ -44,12 +48,44 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
44
48
  end
45
49
  end
46
50
 
51
+ def best_version(should_range)
52
+ available_versions = SortedSet.new
53
+
54
+ output = aptcache :madison, @resource[:name]
55
+ output.each_line do |line|
56
+ is = line.split('|')[1].strip
57
+ begin
58
+ is_version = DebianVersion.parse(is)
59
+ available_versions << is_version if should_range.include?(is_version)
60
+ rescue DebianVersion::ValidationFailure
61
+ Puppet.debug("Cannot parse #{is} as a debian version")
62
+ end
63
+ end
64
+
65
+ return available_versions.to_a.last unless available_versions.empty?
66
+
67
+ Puppet.debug("No available version for package #{@resource[:name]} is included in range #{should_range}")
68
+ should_range
69
+ end
70
+
47
71
  # Install a package using 'apt-get'. This function needs to support
48
72
  # installing a specific version.
49
73
  def install
50
74
  self.run_preseed if @resource[:responsefile]
51
75
  should = @resource[:ensure]
52
76
 
77
+ if should.is_a?(String)
78
+ begin
79
+ should_range = VersionRange.parse(should, DebianVersion)
80
+
81
+ unless should_range.is_a?(VersionRange::Eq)
82
+ should = best_version(should_range)
83
+ end
84
+ rescue VersionRange::ValidationFailure, DebianVersion::ValidationFailure
85
+ Puppet.debug("Cannot parse #{should} as a debian version range, falling through")
86
+ end
87
+ end
88
+
53
89
  checkforcdrom
54
90
  cmd = %w{-q -y}
55
91
 
@@ -75,7 +111,12 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
75
111
  cmd += install_options if @resource[:install_options]
76
112
  cmd << :install << str
77
113
 
78
- aptget(*cmd)
114
+ self.unhold if self.properties[:mark] == :hold
115
+ begin
116
+ aptget(*cmd)
117
+ ensure
118
+ self.hold if @resource[:mark] == :hold
119
+ end
79
120
  end
80
121
 
81
122
  # What's the latest package version available?
@@ -106,12 +147,18 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
106
147
 
107
148
  def uninstall
108
149
  self.run_preseed if @resource[:responsefile]
109
- aptget "-y", "-q", :remove, @resource[:name]
150
+ args = ['-y', '-q']
151
+ args << '--allow-change-held-packages' if self.properties[:mark] == :hold
152
+ args << :remove << @resource[:name]
153
+ aptget(*args)
110
154
  end
111
155
 
112
156
  def purge
113
157
  self.run_preseed if @resource[:responsefile]
114
- aptget '-y', '-q', :remove, '--purge', @resource[:name]
158
+ args = ['-y', '-q']
159
+ args << '--allow-change-held-packages' if self.properties[:mark] == :hold
160
+ args << :remove << '--purge' << @resource[:name]
161
+ aptget(*args)
115
162
  # workaround a "bug" in apt, that already removed packages are not purged
116
163
  super
117
164
  end
@@ -119,4 +166,31 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
119
166
  def install_options
120
167
  join_options(@resource[:install_options])
121
168
  end
169
+
170
+ def insync?(is)
171
+ # this is called after the generic version matching logic (insync? for the
172
+ # type), so we only get here if should != is
173
+
174
+ return false unless is && is != :absent
175
+
176
+ #if 'should' is a range and 'is' a debian version we should check if 'should' includes 'is'
177
+ should = @resource[:ensure]
178
+
179
+ return false unless is.is_a?(String) && should.is_a?(String)
180
+
181
+ begin
182
+ should_range = VersionRange.parse(should, DebianVersion)
183
+ rescue VersionRange::ValidationFailure, DebianVersion::ValidationFailure
184
+ Puppet.debug("Cannot parse #{should} as a debian version range")
185
+ return false
186
+ end
187
+
188
+ begin
189
+ is_version = DebianVersion.parse(is)
190
+ rescue DebianVersion::ValidationFailure
191
+ Puppet.debug("Cannot parse #{is} as a debian version")
192
+ return false
193
+ end
194
+ should_range.include?(is_version)
195
+ end
122
196
  end
@@ -16,7 +16,7 @@ Puppet::Type.type(:package).provide :aptitude, :parent => :apt, :source => :dpkg
16
16
  output = aptitude(*args)
17
17
 
18
18
  # Yay, stupid aptitude doesn't throw an error when the package is missing.
19
- if args.include?(:install) and output =~ /Couldn't find any package/
19
+ if args.include?(:install) and output.to_s =~ /Couldn't find any package/
20
20
  raise Puppet::Error.new(
21
21
  _("Could not find package %{name}") % { name: self.name }
22
22
  )
@@ -12,7 +12,7 @@ require 'puppet/provider/package'
12
12
 
13
13
  Puppet::Type.type(:package).provide :dnfmodule, :parent => :dnf do
14
14
 
15
- has_feature :installable, :uninstallable, :versionable
15
+ has_feature :installable, :uninstallable, :versionable, :supports_flavors, :disableable
16
16
  #has_feature :upgradeable
17
17
  # it's not (yet) feasible to make this upgradeable since module streams don't
18
18
  # always have matching version types (i.e. idm has streams DL1 and client,
@@ -34,14 +34,26 @@ Puppet::Type.type(:package).provide :dnfmodule, :parent => :dnf do
34
34
 
35
35
  def self.instances
36
36
  packages = []
37
- cmd = "#{command(:dnf)} module list --installed -d 0 -e #{error_level}"
37
+ cmd = "#{command(:dnf)} module list -d 0 -e #{error_level}"
38
38
  execute(cmd).each_line do |line|
39
- next unless line =~ /\[i\][, ]/ # get rid of non-package lines (including last Hint line)
40
- line.gsub!(/\[[de]\]/, '') # we don't care about default/enabled flags
39
+ # select only lines with actual packages since DNF clutters the output
40
+ next unless line =~ /\[[eix]\][, ]/
41
+ line.gsub!(/\[d\]/, '') # we don't care about the default flag
42
+
43
+ flavor = if line.include?('[i]')
44
+ line.split('[i]').first.split.last
45
+ else
46
+ :absent
47
+ end
48
+
41
49
  packages << new(
42
50
  name: line.split[0],
43
- ensure: line.split[1],
44
- flavor: line.split('[i]').first.split.last, # this is nasty
51
+ ensure: if line.include?('[x]')
52
+ :disabled
53
+ else
54
+ line.split[1]
55
+ end,
56
+ flavor: flavor,
45
57
  provider: name
46
58
  )
47
59
  end
@@ -55,33 +67,75 @@ Puppet::Type.type(:package).provide :dnfmodule, :parent => :dnf do
55
67
  pkg ? pkg.properties : nil
56
68
  end
57
69
 
58
- def reset
59
- execute([command(:dnf), 'module', 'reset', '-d', '0', '-e', self.class.error_level, '-y', @resource[:name]])
60
- end
61
-
62
70
  # to install specific streams and profiles:
63
71
  # $ dnf module install module-name:stream/profile
64
72
  # $ dnf module install perl:5.24/minimal
65
73
  # if unspecified, they will be defaulted (see [d] param in dnf module list output)
66
74
  def install
67
- args = @resource[:name]
68
75
  # ensure we start fresh (remove existing stream)
69
76
  uninstall unless [:absent, :purged].include?(@property_hash[:ensure])
77
+
78
+ args = @resource[:name].dup
70
79
  case @resource[:ensure]
71
80
  when true, false, Symbol
72
81
  # pass
73
82
  else
74
83
  args << ":#{@resource[:ensure]}"
75
84
  end
76
- if @resource[:flavor]
77
- args << "/#{@resource[:flavor]}"
85
+ args << "/#{@resource[:flavor]}" if @resource[:flavor]
86
+
87
+ if @resource[:enable_only] == true
88
+ enable(args)
89
+ else
90
+ begin
91
+ execute([command(:dnf), 'module', 'install', '-d', '0', '-e', self.class.error_level, '-y', args])
92
+ rescue Puppet::ExecutionFailure => e
93
+ # module has no default profile and no profile was requested, so just enable the stream
94
+ # DNF versions prior to 4.2.8 do not need this workaround
95
+ # see https://bugzilla.redhat.com/show_bug.cgi?id=1669527
96
+ if @resource[:flavor] == nil && e.message =~ /^missing groups or modules: #{Regexp.quote(@resource[:name])}$/
97
+ enable(args)
98
+ else
99
+ raise
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ # should only get here when @resource[ensure] is :disabled
106
+ def insync?(is)
107
+ if resource[:ensure] == :disabled
108
+ # in sync only if package is already disabled
109
+ pkg = self.class.instances.find do |package|
110
+ @resource[:name] == package.name && package.properties[:ensure] == :disabled
111
+ end
112
+ return true if pkg
78
113
  end
79
- execute([command(:dnf), 'module', 'install', '-d', '0', '-e', self.class.error_level, '-y', args])
114
+ return false
115
+ end
116
+
117
+ def enable(args = @resource[:name])
118
+ execute([command(:dnf), 'module', 'enable', '-d', '0', '-e', self.class.error_level, '-y', args])
80
119
  end
81
120
 
82
121
  def uninstall
83
122
  execute([command(:dnf), 'module', 'remove', '-d', '0', '-e', self.class.error_level, '-y', @resource[:name]])
84
123
  reset # reset module to the default stream
85
124
  end
86
- end
87
125
 
126
+ def disable(args = @resource[:name])
127
+ execute([command(:dnf), 'module', 'disable', '-d', '0', '-e', self.class.error_level, '-y', args])
128
+ end
129
+
130
+ def reset
131
+ execute([command(:dnf), 'module', 'reset', '-d', '0', '-e', self.class.error_level, '-y', @resource[:name]])
132
+ end
133
+
134
+ def flavor
135
+ @property_hash[:flavor]
136
+ end
137
+
138
+ def flavor=(value)
139
+ install if flavor != @resource.should(:flavor)
140
+ end
141
+ end
@@ -45,8 +45,8 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
45
45
  # eventually become this Puppet::Type::Package::ProviderDpkg class.
46
46
  self::DPKG_QUERY_FORMAT_STRING = %Q{'${Status} ${Package} ${Version}\\n'}
47
47
  self::DPKG_QUERY_PROVIDES_FORMAT_STRING = %Q{'${Status} ${Package} ${Version} [${Provides}]\\n'}
48
- self::FIELDS_REGEX = %r{^(\S+) +(\S+) +(\S+) (\S+) (\S*)$}
49
- self::FIELDS_REGEX_WITH_PROVIDES = %r{^(\S+) +(\S+) +(\S+) (\S+) (\S*) \[.*\]$}
48
+ self::FIELDS_REGEX = %r{^'?(\S+) +(\S+) +(\S+) (\S+) (\S*)$}
49
+ self::FIELDS_REGEX_WITH_PROVIDES = %r{^'?(\S+) +(\S+) +(\S+) (\S+) (\S*) \[.*\]$}
50
50
  self::FIELDS= [:desired, :error, :status, :name, :ensure]
51
51
 
52
52
  def self.defaultto_allow_virtual
@@ -74,7 +74,7 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
74
74
  elsif ['config-files', 'half-installed', 'unpacked', 'half-configured'].include?(hash[:status])
75
75
  hash[:ensure] = :absent
76
76
  end
77
- hash[:ensure] = :held if hash[:desired] == 'hold'
77
+ hash[:mark] = :hold if hash[:desired] == 'hold'
78
78
  else
79
79
  Puppet.debug("Failed to match dpkg-query line #{line.inspect}")
80
80
  end
@@ -91,8 +91,6 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
91
91
  end
92
92
  args = []
93
93
 
94
- # We always unhold when installing to remove any prior hold.
95
- self.unhold
96
94
 
97
95
  if @resource[:configfiles] == :keep
98
96
  args << '--force-confold'
@@ -101,7 +99,12 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
101
99
  end
102
100
  args << '-i' << file
103
101
 
104
- dpkg(*args)
102
+ self.unhold if self.properties[:mark] == :hold
103
+ begin
104
+ dpkg(*args)
105
+ ensure
106
+ self.hold if @resource[:mark] == :hold
107
+ end
105
108
  end
106
109
 
107
110
  def update
@@ -170,10 +173,14 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
170
173
  dpkg "--purge", @resource[:name]
171
174
  end
172
175
 
173
- def hold
176
+ def deprecated_hold
174
177
  if package_not_installed?
175
178
  self.install
176
179
  end
180
+ hold
181
+ end
182
+
183
+ def hold
177
184
  Tempfile.open('puppet_dpkg_set_selection') do |tmpfile|
178
185
  tmpfile.write("#{@resource[:name]} hold\n")
179
186
  tmpfile.flush
@@ -37,7 +37,12 @@ Puppet::Type.type(:package).provide :fink, :parent => :dpkg, :source => :dpkg do
37
37
 
38
38
  cmd << :install << str
39
39
 
40
- finkcmd(cmd)
40
+ self.unhold if self.properties[:mark] == :hold
41
+ begin
42
+ finkcmd(cmd)
43
+ ensure
44
+ self.hold if @resource[:mark] == :hold
45
+ end
41
46
  end
42
47
 
43
48
  # What's the latest package version available?
@@ -71,10 +76,22 @@ Puppet::Type.type(:package).provide :fink, :parent => :dpkg, :source => :dpkg do
71
76
  end
72
77
 
73
78
  def uninstall
74
- finkcmd "-y", "-q", :remove, @model[:name]
79
+ self.unhold if self.properties[:mark] == :hold
80
+ begin
81
+ finkcmd "-y", "-q", :remove, @model[:name]
82
+ rescue StandardError, LoadError => e
83
+ self.hold if self.properties[:mark] == :hold
84
+ raise e
85
+ end
75
86
  end
76
87
 
77
88
  def purge
78
- aptget '-y', '-q', 'remove', '--purge', @resource[:name]
89
+ self.unhold if self.properties[:mark] == :hold
90
+ begin
91
+ aptget '-y', '-q', 'remove', '--purge', @resource[:name]
92
+ rescue StandardError, LoadError => e
93
+ self.hold if self.properties[:mark] == :hold
94
+ raise e
95
+ end
79
96
  end
80
97
  end
@@ -1,3 +1,5 @@
1
+ require 'puppet/util/package/version/gem'
2
+ require 'puppet/util/package/version/range'
1
3
  require 'puppet/provider/package_targetable'
2
4
  require 'uri'
3
5
 
@@ -15,7 +17,10 @@ Puppet::Type.type(:package).provide :gem, :parent => Puppet::Provider::Package::
15
17
  These options should be specified as an array where each element is either a
16
18
  string or a hash."
17
19
 
18
- has_feature :versionable, :install_options, :uninstall_options, :targetable
20
+ has_feature :versionable, :install_options, :uninstall_options, :targetable, :version_ranges
21
+
22
+ GEM_VERSION = Puppet::Util::Package::Version::Gem
23
+ GEM_VERSION_RANGE = Puppet::Util::Package::Version::Range
19
24
 
20
25
  # Override the specificity method to return 1 if gem is not set as default provider
21
26
  def self.specificity
@@ -125,16 +130,35 @@ Puppet::Type.type(:package).provide :gem, :parent => Puppet::Provider::Package::
125
130
 
126
131
  def insync?(is)
127
132
  return false unless is && is != :absent
133
+ is = [is] unless is.is_a? Array
134
+ should = @resource[:ensure]
128
135
 
136
+ unless should =~ Regexp.union(/,/, Gem::Requirement::PATTERN)
137
+ begin
138
+ should_range = GEM_VERSION_RANGE.parse(should, GEM_VERSION)
139
+ rescue GEM_VERSION_RANGE::ValidationFailure, GEM_VERSION::ValidationFailure
140
+ Puppet.debug("Cannot parse #{should} as a ruby gem version range")
141
+ return false
142
+ end
143
+
144
+ return is.any? do |version|
145
+ begin
146
+ should_range.include?(GEM_VERSION.parse(version))
147
+ rescue GEM_VERSION::ValidationFailure
148
+ Puppet.debug("Cannot parse #{version} as a ruby gem version")
149
+ false
150
+ end
151
+ end
152
+ end
153
+
129
154
  begin
130
- dependency = Gem::Dependency.new('', resource[:ensure])
155
+ # Range intersections are not supported by Gem::Requirement, so just split by comma.
156
+ dependency = Gem::Dependency.new('', should.split(','))
131
157
  rescue ArgumentError
132
158
  # Bad requirements will cause an error during gem command invocation, so just return not in sync
133
159
  return false
134
160
  end
135
161
 
136
- is = [is] unless is.is_a? Array
137
-
138
162
  # Check if any version matches the dependency
139
163
  is.any? { |version| dependency.match?('', version) }
140
164
  end
@@ -148,12 +172,22 @@ Puppet::Type.type(:package).provide :gem, :parent => Puppet::Provider::Package::
148
172
  command = resource_or_provider_command
149
173
  command_options = ["install"]
150
174
  command_options += install_options if resource[:install_options]
175
+ should = resource[:ensure]
176
+
177
+ unless should =~ Regexp.union(/,/, Gem::Requirement::PATTERN)
178
+ begin
179
+ should_range = GEM_VERSION_RANGE.parse(should, GEM_VERSION)
180
+ should = should_range.to_gem_version
181
+ useversion = true
182
+ rescue GEM_VERSION_RANGE::ValidationFailure, GEM_VERSION::ValidationFailure
183
+ Puppet.debug("Cannot parse #{should} as a ruby gem version range. Falling through.")
184
+ end
185
+ end
151
186
 
152
187
  if Puppet::Util::Platform.windows?
153
- version = resource[:ensure]
154
- command_options << "-v" << %Q["#{version}"] if (! resource[:ensure].is_a? Symbol) and useversion
188
+ command_options << "-v" << %Q["#{should}"] if useversion && !should.is_a?(Symbol)
155
189
  else
156
- command_options << "-v" << resource[:ensure] if (! resource[:ensure].is_a? Symbol) and useversion
190
+ command_options << "-v" << should if useversion && !should.is_a?(Symbol)
157
191
  end
158
192
 
159
193
  if Puppet::Util::Package.versioncmp(rubygem_version(command), '2.0.0') == -1