puppet 6.11.1 → 6.16.0

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
@@ -176,6 +176,19 @@ describe Puppet::Type.type(:package).provider(:zypper) do
176
176
  @provider.install
177
177
  end
178
178
 
179
+ it "should install the package with --no-gpg-checks" do
180
+ allow(@resource).to receive(:[]).with(:name).and_return("php5")
181
+ allow(@resource).to receive(:[]).with(:install_options).and_return(['--no-gpg-checks', {'-p' => '/vagrant/files/localrepo/'}])
182
+ allow(@resource).to receive(:should).with(:ensure).and_return("5.4.10-4.5.6")
183
+ allow(@resource).to receive(:allow_virtual?).and_return(false)
184
+ allow(@provider).to receive(:zypper_version).and_return("1.2.8")
185
+
186
+ expect(@provider).to receive(:zypper).with('--quiet', '--no-gpg-checks', :install,
187
+ '--auto-agree-with-licenses', '--no-confirm', '-p=/vagrant/files/localrepo/', 'php5-5.4.10-4.5.6')
188
+ expect(@provider).to receive(:query).and_return("php5 0 5.4.10 4.5.6 x86_64")
189
+ @provider.install
190
+ end
191
+
179
192
  it "should install package with hash install options" do
180
193
  allow(@resource).to receive(:[]).with(:name).and_return('vim')
181
194
  allow(@resource).to receive(:[]).with(:install_options).and_return([{ '--a' => 'foo', '--b' => '"quoted bar"' }])
@@ -226,4 +239,75 @@ describe Puppet::Type.type(:package).provider(:zypper) do
226
239
  @provider.uninstall
227
240
  end
228
241
  end
242
+
243
+ context 'when installing with VersionRange' do
244
+ let(:search_output) { File.read(my_fixture('zypper-search-uninstalled.out')) }
245
+
246
+ before(:each) do
247
+ allow(@resource).to receive(:[]).with(:name).and_return('vim')
248
+ allow(@resource).to receive(:allow_virtual?).and_return(false)
249
+ allow(@provider).to receive(:zypper_version).and_return('1.0.2')
250
+
251
+ expect(@provider).to receive(:zypper).with('search', '--match-exact', '--type', 'package', '--uninstalled-only', '-s', 'vim')
252
+ .and_return(search_output)
253
+ end
254
+
255
+ it 'does install the package if version is available' do
256
+ expect(@resource).to receive(:should).with(:ensure).and_return('>1.0')
257
+
258
+ expect(@provider).to receive(:zypper).with('--quiet', :install, '--auto-agree-with-licenses', '--no-confirm', 'vim-1.0.20040813-19.9')
259
+ expect(@provider).to receive(:query).and_return('vim 0 1.0.20040813 19.9 x86_64')
260
+
261
+ @provider.install
262
+ end
263
+
264
+ it 'does consider range as version if version in range is not available' do
265
+ allow(@resource).to receive(:should).with(:ensure).and_return('>2.0')
266
+
267
+ expect(@provider).to receive(:zypper).with('--quiet', :install, '--auto-agree-with-licenses', '--no-confirm', 'vim->2.0')
268
+ .and_raise(Puppet::ExecutionFailure.new('My Error'))
269
+
270
+ expect { @provider.install }.to raise_error(Puppet::ExecutionFailure, 'My Error')
271
+ end
272
+ end
273
+
274
+ describe 'insync?' do
275
+ subject { @provider.insync?('1.19-2') }
276
+
277
+ context 'when versions are matching' do
278
+ before { allow(@resource).to receive(:[]).with(:ensure).and_return('1.19-2') }
279
+
280
+ it { is_expected.to be true }
281
+ end
282
+
283
+ context 'when version are not matching' do
284
+ before { allow(@resource).to receive(:[]).with(:ensure).and_return('1.19-3') }
285
+
286
+ it { is_expected.to be false }
287
+ end
288
+
289
+ context 'when version is in gt range' do
290
+ before { allow(@resource).to receive(:[]).with(:ensure).and_return('>1.19-0') }
291
+
292
+ it { is_expected.to be true }
293
+ end
294
+
295
+ context 'when version is not in gt range' do
296
+ before { allow(@resource).to receive(:[]).with(:ensure).and_return('>1.19-2') }
297
+
298
+ it { is_expected.to be false }
299
+ end
300
+
301
+ context 'when version is in min-max range' do
302
+ before { allow(@resource).to receive(:[]).with(:ensure).and_return('>1.19-0 <1.19-3') }
303
+
304
+ it { is_expected.to be true }
305
+ end
306
+
307
+ context 'when version is not in min-max range' do
308
+ before { allow(@resource).to receive(:[]).with(:ensure).and_return('>1.19-0 <1.19-2') }
309
+
310
+ it { is_expected.to be false }
311
+ end
312
+ end
229
313
  end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+ require 'puppet'
3
+ require 'puppet/provider/package_targetable'
4
+ require 'puppet/provider/package/gem'
5
+
6
+ describe Puppet::Provider::Package::Targetable do
7
+ let(:provider) { Puppet::Type.type(:package).provider(:gem) }
8
+ let(:command) { '/opt/bin/gem' }
9
+
10
+ describe "when prefetching" do
11
+ context "with a package without a command attribute" do
12
+ let(:resource) { Puppet::Type.type(:package).new(:name => 'noo', :provider => 'gem', :ensure => :present) }
13
+ let(:catalog) { Puppet::Resource::Catalog.new }
14
+ let(:instance) { provider.new(resource) }
15
+ let(:packages) { { 'noo' => resource } }
16
+
17
+ it "should pass a command to the instances method of the provider" do
18
+ catalog.add_resource(resource)
19
+ expect(provider).to receive(:instances).with(nil).and_return([instance])
20
+ expect(provider.prefetch(packages)).to eq([nil]) # prefetch arbitrarily returns the array of commands for a provider in the catalog
21
+ end
22
+ end
23
+
24
+ context "with a package with a command attribute" do
25
+ let(:resource) { Puppet::Type.type(:package).new(:name => 'noo', :provider => 'gem', :ensure => :present) }
26
+ let(:resource_targeted) { Puppet::Type.type(:package).new(:name => 'yes', :provider => 'gem', :command => command, :ensure => :present) }
27
+ let(:catalog) { Puppet::Resource::Catalog.new }
28
+ let(:instance) { provider.new(resource) }
29
+ let(:instance_targeted) { provider.new(resource_targeted) }
30
+ let(:packages) { { 'noo' => resource, 'yes' => resource_targeted } }
31
+
32
+ it "should pass the command to the instances method of the provider" do
33
+ catalog.add_resource(resource)
34
+ catalog.add_resource(resource_targeted)
35
+ expect(provider).to receive(:instances).with(nil).and_return([instance])
36
+ expect(provider).to receive(:instances).with(command).and_return([instance_targeted]).once
37
+ expect(provider.prefetch(packages)).to eq([nil, command]) # prefetch arbitrarily returns the array of commands for a provider in the catalog
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "when validating a command" do
43
+ context "with no command" do
44
+ it "report not functional" do
45
+ expect { provider.validate_command(nil) }.to raise_error(Puppet::Error, "Provider gem package command is not functional on this host")
46
+ end
47
+ end
48
+ context "with a missing command" do
49
+ it "report does not exist" do
50
+ expect { provider.validate_command(command) }.to raise_error(Puppet::Error, "Provider gem package command '#{command}' does not exist on this host")
51
+ end
52
+ end
53
+ context "with an existing command" do
54
+ it "validates" do
55
+ allow(File).to receive(:file?).with(command).and_return(true)
56
+ expect { provider.validate_command(command) }.not_to raise_error
57
+ end
58
+ end
59
+ end
60
+ end
@@ -150,6 +150,7 @@ describe 'Puppet::Type::Service::Provider::Init', unless: Puppet::Util::Platform
150
150
 
151
151
  describe "if the init script is present" do
152
152
  before :each do
153
+ allow(File).to receive(:directory?).and_call_original
153
154
  allow(File).to receive(:directory?).with("/service/path").and_return(true)
154
155
  allow(File).to receive(:directory?).with("/alt/service/path").and_return(true)
155
156
  allow(Puppet::FileSystem).to receive(:exist?).with("/service/path/myservice").and_return(true)
@@ -12,6 +12,15 @@ describe 'Puppet::Type::Service::Provider::Openbsd',
12
12
  allow(FileTest).to receive(:executable?).with('/usr/sbin/rcctl').and_return(true)
13
13
  end
14
14
 
15
+ # `execute` and `texecute` start a new process, consequently setting $CHILD_STATUS to a Process::Status instance,
16
+ # but because they are mocked, an external process is never executed and $CHILD_STATUS remain nil.
17
+ # In order to execute some parts of the code under test and to mock $CHILD_STATUS, we need this variable to be a
18
+ # Process::Status instance. We can achieve this by starting a process that does nothing (exit 0). By doing this,
19
+ # $CHILD_STATUS will be initialised with a instance of Process::Status and we will be able to mock it.
20
+ before(:all) do
21
+ `exit 0`
22
+ end
23
+
15
24
  context "#instances" do
16
25
  it "should have an instances method" do
17
26
  expect(provider_class).to respond_to :instances
@@ -28,6 +28,7 @@ describe 'Puppet::Type::Service::Provider::Openwrt',
28
28
  allow(FileTest).to receive(:executable?).with('/etc/rc.common').and_return(true)
29
29
 
30
30
  # All OpenWrt tests operate on the init script directly. It must exist.
31
+ allow(File).to receive(:directory?).and_call_original
31
32
  allow(File).to receive(:directory?).with('/etc/init.d').and_return(true)
32
33
 
33
34
  allow(Puppet::FileSystem).to receive(:exist?).with('/etc/init.d/myservice').and_return(true)
@@ -4,6 +4,15 @@ describe 'Puppet::Type::Service::Provider::Redhat',
4
4
  if: Puppet.features.posix? && !Puppet::Util::Platform.jruby?do
5
5
  let(:provider_class) { Puppet::Type.type(:service).provider(:redhat) }
6
6
 
7
+ # `execute` and `texecute` start a new process, consequently setting $CHILD_STATUS to a Process::Status instance,
8
+ # but because they are mocked, an external process is never executed and $CHILD_STATUS remain nil.
9
+ # In order to execute some parts of the code under test and to mock $CHILD_STATUS, we need this variable to be a
10
+ # Process::Status instance. We can achieve this by starting a process that does nothing (exit 0). By doing this,
11
+ # $CHILD_STATUS will be initialised with a instance of Process::Status and we will be able to mock it.
12
+ before(:all) do
13
+ `exit 0`
14
+ end
15
+
7
16
  before :each do
8
17
  @class = Puppet::Type.type(:service).provider(:redhat)
9
18
  @resource = double('resource')
@@ -13,6 +13,15 @@ describe 'Puppet::Type::Service::Provider::Systemd', unless: Puppet::Util::Platf
13
13
  allow(provider_class).to receive(:which).with('systemctl').and_return('/bin/systemctl')
14
14
  end
15
15
 
16
+ # `execute` and `texecute` start a new process, consequently setting $CHILD_STATUS to a Process::Status instance,
17
+ # but because they are mocked, an external process is never executed and $CHILD_STATUS remain nil.
18
+ # In order to execute some parts of the code under test and to mock $CHILD_STATUS, we need this variable to be a
19
+ # Process::Status instance. We can achieve this by starting a process that does nothing (exit 0). By doing this,
20
+ # $CHILD_STATUS will be initialised with a instance of Process::Status and we will be able to mock it.
21
+ before(:all) do
22
+ `exit 0`
23
+ end
24
+
16
25
  let :provider do
17
26
  provider_class.new(:name => 'sshd.service')
18
27
  end
@@ -187,8 +196,18 @@ describe 'Puppet::Type::Service::Provider::Systemd', unless: Puppet::Util::Platf
187
196
  autovt@.service
188
197
  avahi-daemon.service
189
198
  blk-availability.service
199
+ apparmor.service
200
+ umountnfs.service
201
+ urandom.service
202
+ brandbot.service
190
203
  })
191
204
  end
205
+
206
+ it "should print a debug message when a service with the state `bad` is found" do
207
+ expect(provider_class).to receive(:systemctl).with('list-unit-files', '--type', 'service', '--full', '--all', '--no-pager').and_return(File.read(my_fixture('list_unit_files_services')))
208
+ expect(Puppet).to receive(:debug).with("apparmor.service marked as bad by `systemctl`. It is recommended to be further checked.")
209
+ provider_class.instances
210
+ end
192
211
  end
193
212
 
194
213
  describe "#start" do
@@ -269,43 +288,43 @@ Jun 14 21:43:23 foo.example.com systemd[1]: sshd.service lacks both ExecStart= a
269
288
  describe "#enabled?" do
270
289
  it "should return :true if the service is enabled" do
271
290
  provider = provider_class.new(Puppet::Type.type(:service).new(:name => 'sshd.service'))
272
- expect(provider).to receive(:execute).with(['/bin/systemctl','is-enabled', '--', 'sshd.service'], :failonfail => false).and_return("enabled\n")
273
- allow($CHILD_STATUS).to receive(:exitstatus).and_return(0)
291
+ expect(provider).to receive(:execute).with(['/bin/systemctl','is-enabled', '--', 'sshd.service'], :failonfail => false).
292
+ and_return(Puppet::Util::Execution::ProcessOutput.new("enabled\n", 0))
274
293
  expect(provider.enabled?).to eq(:true)
275
294
  end
276
295
 
277
296
  it "should return :true if the service is static" do
278
297
  provider = provider_class.new(Puppet::Type.type(:service).new(:name => 'sshd.service'))
279
- expect(provider).to receive(:execute).with(['/bin/systemctl','is-enabled','--', 'sshd.service'], :failonfail => false).and_return("static\n")
280
- allow($CHILD_STATUS).to receive(:exitstatus).and_return(0)
298
+ expect(provider).to receive(:execute).with(['/bin/systemctl','is-enabled','--', 'sshd.service'], :failonfail => false).
299
+ and_return(Puppet::Util::Execution::ProcessOutput.new("static\n", 0))
281
300
  expect(provider.enabled?).to eq(:true)
282
301
  end
283
302
 
284
303
  it "should return :false if the service is disabled" do
285
304
  provider = provider_class.new(Puppet::Type.type(:service).new(:name => 'sshd.service'))
286
- expect(provider).to receive(:execute).with(['/bin/systemctl','is-enabled', '--', 'sshd.service'], :failonfail => false).and_return("disabled\n")
287
- allow($CHILD_STATUS).to receive(:exitstatus).and_return(1)
305
+ expect(provider).to receive(:execute).with(['/bin/systemctl','is-enabled', '--', 'sshd.service'], :failonfail => false).
306
+ and_return(Puppet::Util::Execution::ProcessOutput.new("disabled\n", 1))
288
307
  expect(provider.enabled?).to eq(:false)
289
308
  end
290
309
 
291
310
  it "should return :false if the service is indirect" do
292
311
  provider = provider_class.new(Puppet::Type.type(:service).new(:name => 'sshd.service'))
293
- expect(provider).to receive(:execute).with(['/bin/systemctl','is-enabled', '--', 'sshd.service'], :failonfail => false).and_return("indirect\n")
294
- allow($CHILD_STATUS).to receive(:exitstatus).and_return(0)
312
+ expect(provider).to receive(:execute).with(['/bin/systemctl','is-enabled', '--', 'sshd.service'], :failonfail => false).
313
+ and_return(Puppet::Util::Execution::ProcessOutput.new("indirect\n", 0))
295
314
  expect(provider.enabled?).to eq(:false)
296
315
  end
297
316
 
298
317
  it "should return :false if the service is masked and the resource is attempting to be disabled" do
299
318
  provider = provider_class.new(Puppet::Type.type(:service).new(:name => 'sshd.service', :enable => false))
300
- expect(provider).to receive(:execute).with(['/bin/systemctl','is-enabled', '--', 'sshd.service'], :failonfail => false).and_return("masked\n")
301
- allow($CHILD_STATUS).to receive(:exitstatus).and_return(1)
319
+ expect(provider).to receive(:execute).with(['/bin/systemctl','is-enabled', '--', 'sshd.service'], :failonfail => false).
320
+ and_return(Puppet::Util::Execution::ProcessOutput.new("masked\n", 1))
302
321
  expect(provider.enabled?).to eq(:false)
303
322
  end
304
323
 
305
324
  it "should return :mask if the service is masked and the resource is attempting to be masked" do
306
325
  provider = provider_class.new(Puppet::Type.type(:service).new(:name => 'sshd.service', :enable => 'mask'))
307
- expect(provider).to receive(:execute).with(['/bin/systemctl','is-enabled', '--', 'sshd.service'], :failonfail => false).and_return("masked\n")
308
- allow($CHILD_STATUS).to receive(:exitstatus).and_return(1)
326
+ expect(provider).to receive(:execute).with(['/bin/systemctl','is-enabled', '--', 'sshd.service'], :failonfail => false).
327
+ and_return(Puppet::Util::Execution::ProcessOutput.new("masked\n", 1))
309
328
  expect(provider.enabled?).to eq(:mask)
310
329
  end
311
330
  end
@@ -428,6 +447,67 @@ Jun 14 21:43:23 foo.example.com systemd[1]: sshd.service lacks both ExecStart= a
428
447
  end
429
448
  end
430
449
 
450
+ describe "#insync_enabled?" do
451
+ let(:provider) do
452
+ provider_class.new(Puppet::Type.type(:service).new(:name => 'sshd.service', :enable => false))
453
+ end
454
+
455
+ before do
456
+ allow(provider).to receive(:cached_enabled?).and_return({ output: service_state, exitcode: 0 })
457
+ end
458
+
459
+ context 'when service state is static' do
460
+ let(:service_state) { 'static' }
461
+
462
+ it 'is always enabled_insync even if current value is the same as expected' do
463
+ expect(provider).to be_enabled_insync(:false)
464
+ end
465
+
466
+ it 'is always enabled_insync even if current value is not the same as expected' do
467
+ expect(provider).to be_enabled_insync(:true)
468
+ end
469
+
470
+ it 'logs a debug messsage' do
471
+ expect(Puppet).to receive(:debug).with("Unable to enable or disable static service sshd.service")
472
+ provider.enabled_insync?(:true)
473
+ end
474
+ end
475
+
476
+ context 'when service state is indirect' do
477
+ let(:service_state) { 'indirect' }
478
+
479
+ it 'is always enabled_insync even if current value is the same as expected' do
480
+ expect(provider).to be_enabled_insync(:false)
481
+ end
482
+
483
+ it 'is always enabled_insync even if current value is not the same as expected' do
484
+ expect(provider).to be_enabled_insync(:true)
485
+ end
486
+
487
+ it 'logs a debug messsage' do
488
+ expect(Puppet).to receive(:debug).with("Service sshd.service is in 'indirect' state and cannot be enabled/disabled")
489
+ provider.enabled_insync?(:true)
490
+ end
491
+ end
492
+
493
+ context 'when service state is enabled' do
494
+ let(:service_state) { 'enabled' }
495
+
496
+ it 'is enabled_insync if current value is the same as expected' do
497
+ expect(provider).to be_enabled_insync(:false)
498
+ end
499
+
500
+ it 'is not enabled_insync if current value is not the same as expected' do
501
+ expect(provider).not_to be_enabled_insync(:true)
502
+ end
503
+
504
+ it 'logs no debug messsage' do
505
+ expect(Puppet).not_to receive(:debug)
506
+ provider.enabled_insync?(:true)
507
+ end
508
+ end
509
+ end
510
+
431
511
  describe "#get_start_link_count" do
432
512
  it "should strip the '.service' from the search if present in the resource name" do
433
513
  provider = provider_class.new(Puppet::Type.type(:service).new(:name => 'sshd.service'))
@@ -196,6 +196,17 @@ describe Puppet::Type.type(:user).provider(:directoryservice) do
196
196
  }
197
197
  end
198
198
 
199
+ let (:dsimport_preamble) do
200
+ '0x0A 0x5C 0x3A 0x2C dsRecTypeStandard:Users 2 dsAttrTypeStandard:RecordName base64:dsAttrTypeNative:ShadowHashData'
201
+ end
202
+
203
+ let (:dsimport_contents) do
204
+ <<-DSIMPORT
205
+ #{dsimport_preamble}
206
+ #{username}:#{Base64.strict_encode64(sha512_embedded_bplist)}
207
+ DSIMPORT
208
+ end
209
+
199
210
  # The below represents output of 'dscl -plist . readall /Users' converted to
200
211
  # a native Ruby hash if only one user were installed on the system.
201
212
  # This lets us check the behavior of all the methods necessary to return a
@@ -960,6 +971,24 @@ end
960
971
  end
961
972
  end
962
973
 
974
+ describe '#set_shadow_hash_data' do
975
+ let(:users_plist) { {'ShadowHashData' => ['string_data'] } }
976
+
977
+ it 'should flush the plist data to disk on OS X < 10.15' do
978
+ allow(provider.class).to receive(:get_os_version).and_return('10.12')
979
+
980
+ expect(provider).to receive(:write_users_plist_to_disk)
981
+ provider.set_shadow_hash_data(users_plist, pbkdf2_embedded_plist)
982
+ end
983
+
984
+ it 'should flush the plist data a temporary file on OS X >= 10.15' do
985
+ allow(provider.class).to receive(:get_os_version).and_return('10.15')
986
+
987
+ expect(provider).to receive(:write_and_import_shadow_hash_data)
988
+ provider.set_shadow_hash_data(users_plist, pbkdf2_embedded_plist)
989
+ end
990
+ end
991
+
963
992
  describe '#set_salted_pbkdf2' do
964
993
  let(:users_plist) { {'ShadowHashData' => ['string_data'] } }
965
994
  let(:entropy_shadow_hash_data) do
@@ -1011,6 +1040,18 @@ end
1011
1040
  end
1012
1041
  end
1013
1042
 
1043
+ describe '#write_and_import_shadow_hash_data' do
1044
+ it 'should save the passed plist to a temporary file and import it' do
1045
+ tmpfile = double('tempfile', :path => "/tmp/dsimport_#{username}", :flush => nil)
1046
+ allow(Tempfile).to receive(:create).and_yield(tmpfile)
1047
+ allow(provider).to receive(:dscl).with('.', 'delete', user_path, 'ShadowHashData')
1048
+
1049
+ expect(tmpfile).to receive(:write).with(dsimport_contents)
1050
+ expect(provider).to receive(:dsimport).with(tmpfile.path, '/Local/Default', 'M')
1051
+ provider.write_and_import_shadow_hash_data(sha512_embedded_bplist)
1052
+ end
1053
+ end
1054
+
1014
1055
  describe '#merge_attribute_with_dscl' do
1015
1056
  it 'should raise an error if a dscl command raises an error' do
1016
1057
  expect(provider).to receive(:dscl).with('.', '-merge', user_path, 'GeneratedUID', 'GUID').and_raise(Puppet::ExecutionFailure, 'boom')
@@ -58,14 +58,14 @@ describe Puppet::Type.type(:user).provider(:hpuxuseradd),
58
58
  it "should add modprpw to modifycmd if Trusted System" do
59
59
  allow(resource).to receive(:allowdupe?).and_return(true)
60
60
  expect(provider).to receive(:exec_getprpw).with('root','-m uid').and_return('uid=0')
61
- expect(provider).to receive(:execute).with(['/usr/sam/lbin/usermod.sam', '-u', 1000, '-o', 'testuser', '-F', ';', '/usr/lbin/modprpw', '-v', '-l', 'testuser'], hash_including(custom_environment: {}))
61
+ expect(provider).to receive(:execute).with(['/usr/sam/lbin/usermod.sam', '-F', '-u', 1000, '-o', 'testuser', ';', '/usr/lbin/modprpw', '-v', '-l', 'testuser'], hash_including(custom_environment: {}))
62
62
  provider.uid = 1000
63
63
  end
64
64
 
65
65
  it "should not add modprpw if not Trusted System" do
66
66
  allow(resource).to receive(:allowdupe?).and_return(true)
67
67
  expect(provider).to receive(:exec_getprpw).with('root','-m uid').and_return('System is not trusted')
68
- expect(provider).to receive(:execute).with(['/usr/sam/lbin/usermod.sam', '-u', 1000, '-o', 'testuser', '-F'], hash_including(custom_environment: {}))
68
+ expect(provider).to receive(:execute).with(['/usr/sam/lbin/usermod.sam', '-F', '-u', 1000, '-o', 'testuser'], hash_including(custom_environment: {}))
69
69
  provider.uid = 1000
70
70
  end
71
71
  end
@@ -124,7 +124,7 @@ describe Puppet::Type.type(:user).provider(:useradd) do
124
124
 
125
125
  describe "on systems with the libuser and forcelocal=true" do
126
126
  before do
127
- described_class.has_feature :libuser
127
+ described_class.has_feature :manages_local_users_and_groups
128
128
  resource[:forcelocal] = true
129
129
  end
130
130
 
@@ -188,7 +188,7 @@ describe Puppet::Type.type(:user).provider(:useradd) do
188
188
 
189
189
  describe 'when modifying the password' do
190
190
  before do
191
- described_class.has_feature :libuser
191
+ described_class.has_feature :manages_local_users_and_groups
192
192
  described_class.has_feature :manages_passwords
193
193
  #Setting any resource value here initializes needed variables and methods in the resource and provider
194
194
  #Setting a password value here initializes the existence and management of the password parameter itself
@@ -210,7 +210,7 @@ describe Puppet::Type.type(:user).provider(:useradd) do
210
210
  describe '#modify' do
211
211
  describe "on systems with the libuser and forcelocal=false" do
212
212
  before do
213
- described_class.has_feature :libuser
213
+ described_class.has_feature :manages_local_users_and_groups
214
214
  resource[:forcelocal] = false
215
215
  end
216
216
 
@@ -315,16 +315,24 @@ describe Puppet::Type.type(:user).provider(:useradd) do
315
315
  expect(provider).to receive(:execute).with(['/usr/sbin/usermod', '-e', '', 'myuser'], hash_including(custom_environment: {}))
316
316
  provider.expiry = :absent
317
317
  end
318
+
319
+ it "should use -e with -1 when the expiry property is removed on SLES11" do
320
+ allow(Facter).to receive(:value).with(:operatingsystem).and_return('SLES')
321
+ allow(Facter).to receive(:value).with(:operatingsystemmajrelease).and_return('11')
322
+ resource[:expiry] = :absent
323
+ expect(provider).to receive(:execute).with(['/usr/sbin/usermod', '-e', -1, 'myuser'], hash_including(custom_environment: {}))
324
+ provider.expiry = :absent
325
+ end
318
326
  end
319
327
 
320
328
  describe "#comment" do
321
- before { described_class.has_feature :libuser }
329
+ before { described_class.has_feature :manages_local_users_and_groups }
322
330
 
323
331
  let(:content) { "myuser:x:x:x:local comment:x:x" }
324
332
 
325
333
  it "should return the local comment string when forcelocal is true" do
326
334
  resource[:forcelocal] = true
327
- allow(File).to receive(:open).with('/etc/passwd').and_yield(content)
335
+ allow(File).to receive(:read).with('/etc/passwd').and_return(content)
328
336
  expect(provider.comment).to eq('local comment')
329
337
  end
330
338
 
@@ -337,7 +345,7 @@ describe Puppet::Type.type(:user).provider(:useradd) do
337
345
  end
338
346
 
339
347
  describe "#finduser" do
340
- before { allow(File).to receive(:open).with('/etc/passwd').and_yield(content) }
348
+ before { allow(File).to receive(:read).with('/etc/passwd').and_return(content) }
341
349
 
342
350
  let(:content) { "sample_account:sample_password:sample_uid:sample_gid:sample_gecos:sample_directory:sample_shell" }
343
351
  let(:output) do
@@ -361,6 +369,11 @@ describe Puppet::Type.type(:user).provider(:useradd) do
361
369
  it "returns false when specified key/value pair is not found" do
362
370
  expect(provider.finduser(:account, 'invalid_account')).to eq(false)
363
371
  end
372
+
373
+ it "reads the user file only once per resource" do
374
+ expect(File).to receive(:read).with('/etc/passwd').once
375
+ 5.times { provider.finduser(:account, 'sample_account') }
376
+ end
364
377
  end
365
378
 
366
379
  describe "#check_allow_dup" do
@@ -696,7 +709,7 @@ describe Puppet::Type.type(:user).provider(:useradd) do
696
709
 
697
710
  describe "on systems with the libuser and forcelocal=false" do
698
711
  before do
699
- described_class.has_feature :libuser
712
+ described_class.has_feature :manages_local_users_and_groups
700
713
  resource[:forcelocal] = false
701
714
  end
702
715
 
@@ -708,7 +721,7 @@ describe Puppet::Type.type(:user).provider(:useradd) do
708
721
 
709
722
  describe "on systems with the libuser and forcelocal=true" do
710
723
  before do
711
- described_class.has_feature :libuser
724
+ described_class.has_feature :manages_local_users_and_groups
712
725
  resource[:forcelocal] = true
713
726
  end
714
727