puppet 6.19.1 → 6.23.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 (293) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +2 -16
  3. data/Gemfile +3 -1
  4. data/Gemfile.lock +51 -40
  5. data/ext/osx/puppet.plist +2 -0
  6. data/ext/project_data.yaml +2 -2
  7. data/lib/puppet/application.rb +10 -6
  8. data/lib/puppet/application/agent.rb +12 -4
  9. data/lib/puppet/application/apply.rb +4 -2
  10. data/lib/puppet/application/device.rb +2 -0
  11. data/lib/puppet/application/filebucket.rb +2 -2
  12. data/lib/puppet/application/resource.rb +2 -1
  13. data/lib/puppet/application/script.rb +2 -0
  14. data/lib/puppet/application/ssl.rb +11 -0
  15. data/lib/puppet/application_support.rb +7 -0
  16. data/lib/puppet/configurer.rb +28 -18
  17. data/lib/puppet/configurer/downloader.rb +2 -1
  18. data/lib/puppet/defaults.rb +51 -23
  19. data/lib/puppet/environments.rb +54 -55
  20. data/lib/puppet/face/config.rb +10 -0
  21. data/lib/puppet/face/epp.rb +12 -2
  22. data/lib/puppet/face/facts.rb +158 -0
  23. data/lib/puppet/ffi/posix.rb +10 -0
  24. data/lib/puppet/ffi/posix/constants.rb +14 -0
  25. data/lib/puppet/ffi/posix/functions.rb +24 -0
  26. data/lib/puppet/file_serving/fileset.rb +14 -2
  27. data/lib/puppet/file_system/memory_file.rb +8 -1
  28. data/lib/puppet/file_system/windows.rb +2 -0
  29. data/lib/puppet/functions/all.rb +1 -1
  30. data/lib/puppet/functions/camelcase.rb +1 -1
  31. data/lib/puppet/functions/capitalize.rb +2 -2
  32. data/lib/puppet/functions/downcase.rb +2 -2
  33. data/lib/puppet/functions/epp.rb +1 -0
  34. data/lib/puppet/functions/get.rb +5 -5
  35. data/lib/puppet/functions/group_by.rb +13 -5
  36. data/lib/puppet/functions/inline_epp.rb +1 -0
  37. data/lib/puppet/functions/lest.rb +1 -1
  38. data/lib/puppet/functions/new.rb +100 -100
  39. data/lib/puppet/functions/partition.rb +12 -4
  40. data/lib/puppet/functions/require.rb +5 -5
  41. data/lib/puppet/functions/sort.rb +3 -3
  42. data/lib/puppet/functions/tree_each.rb +7 -9
  43. data/lib/puppet/functions/type.rb +4 -4
  44. data/lib/puppet/functions/upcase.rb +2 -2
  45. data/lib/puppet/http/resolver/server_list.rb +15 -4
  46. data/lib/puppet/http/service/compiler.rb +69 -0
  47. data/lib/puppet/http/service/file_server.rb +2 -1
  48. data/lib/puppet/indirector/catalog/compiler.rb +1 -0
  49. data/lib/puppet/indirector/fact_search.rb +60 -0
  50. data/lib/puppet/indirector/facts/facter.rb +24 -3
  51. data/lib/puppet/indirector/facts/json.rb +27 -0
  52. data/lib/puppet/indirector/facts/yaml.rb +3 -58
  53. data/lib/puppet/indirector/file_metadata/rest.rb +1 -0
  54. data/lib/puppet/indirector/json.rb +5 -1
  55. data/lib/puppet/indirector/node/json.rb +8 -0
  56. data/lib/puppet/indirector/report/json.rb +34 -0
  57. data/lib/puppet/module_tool/applications/installer.rb +48 -2
  58. data/lib/puppet/module_tool/errors/shared.rb +17 -2
  59. data/lib/puppet/network/formats.rb +69 -1
  60. data/lib/puppet/network/http/factory.rb +4 -0
  61. data/lib/puppet/pal/pal_impl.rb +70 -17
  62. data/lib/puppet/parser/ast/leaf.rb +3 -2
  63. data/lib/puppet/parser/functions/fqdn_rand.rb +14 -6
  64. data/lib/puppet/parser/templatewrapper.rb +1 -1
  65. data/lib/puppet/pops/evaluator/deferred_resolver.rb +5 -3
  66. data/lib/puppet/pops/evaluator/evaluator_impl.rb +22 -3
  67. data/lib/puppet/pops/model/ast_transformer.rb +1 -1
  68. data/lib/puppet/pops/types/p_sem_ver_type.rb +8 -2
  69. data/lib/puppet/pops/types/p_sensitive_type.rb +10 -0
  70. data/lib/puppet/property/list.rb +1 -1
  71. data/lib/puppet/provider/group/groupadd.rb +13 -8
  72. data/lib/puppet/provider/package/apt.rb +34 -2
  73. data/lib/puppet/provider/package/aptitude.rb +6 -0
  74. data/lib/puppet/provider/package/dnfmodule.rb +1 -1
  75. data/lib/puppet/provider/package/nim.rb +11 -6
  76. data/lib/puppet/provider/service/debian.rb +2 -0
  77. data/lib/puppet/provider/service/systemd.rb +14 -4
  78. data/lib/puppet/provider/service/windows.rb +38 -0
  79. data/lib/puppet/provider/user/aix.rb +2 -2
  80. data/lib/puppet/provider/user/directoryservice.rb +25 -12
  81. data/lib/puppet/provider/user/useradd.rb +62 -8
  82. data/lib/puppet/reference/configuration.rb +7 -6
  83. data/lib/puppet/settings.rb +33 -28
  84. data/lib/puppet/settings/alias_setting.rb +37 -0
  85. data/lib/puppet/settings/base_setting.rb +26 -2
  86. data/lib/puppet/settings/environment_conf.rb +1 -0
  87. data/lib/puppet/transaction/additional_resource_generator.rb +1 -1
  88. data/lib/puppet/type/file.rb +19 -1
  89. data/lib/puppet/type/file/selcontext.rb +1 -1
  90. data/lib/puppet/type/package.rb +3 -3
  91. data/lib/puppet/type/service.rb +18 -38
  92. data/lib/puppet/type/tidy.rb +21 -2
  93. data/lib/puppet/type/user.rb +38 -20
  94. data/lib/puppet/util/autoload.rb +1 -8
  95. data/lib/puppet/util/fact_dif.rb +81 -0
  96. data/lib/puppet/util/monkey_patches.rb +7 -0
  97. data/lib/puppet/util/posix.rb +54 -5
  98. data/lib/puppet/util/rubygems.rb +5 -1
  99. data/lib/puppet/util/selinux.rb +30 -4
  100. data/lib/puppet/util/windows/adsi.rb +46 -0
  101. data/lib/puppet/util/windows/api_types.rb +1 -1
  102. data/lib/puppet/util/windows/principal.rb +9 -2
  103. data/lib/puppet/util/windows/service.rb +1 -1
  104. data/lib/puppet/util/windows/sid.rb +4 -2
  105. data/lib/puppet/version.rb +1 -1
  106. data/locales/puppet.pot +372 -288
  107. data/man/man5/puppet.conf.5 +282 -254
  108. data/man/man8/puppet-agent.8 +2 -2
  109. data/man/man8/puppet-apply.8 +2 -2
  110. data/man/man8/puppet-catalog.8 +1 -1
  111. data/man/man8/puppet-config.8 +1 -1
  112. data/man/man8/puppet-describe.8 +1 -1
  113. data/man/man8/puppet-device.8 +2 -2
  114. data/man/man8/puppet-doc.8 +1 -1
  115. data/man/man8/puppet-epp.8 +1 -1
  116. data/man/man8/puppet-facts.8 +90 -1
  117. data/man/man8/puppet-filebucket.8 +3 -3
  118. data/man/man8/puppet-generate.8 +1 -1
  119. data/man/man8/puppet-help.8 +1 -1
  120. data/man/man8/puppet-key.8 +1 -1
  121. data/man/man8/puppet-lookup.8 +1 -1
  122. data/man/man8/puppet-man.8 +1 -1
  123. data/man/man8/puppet-module.8 +1 -1
  124. data/man/man8/puppet-node.8 +4 -1
  125. data/man/man8/puppet-parser.8 +1 -1
  126. data/man/man8/puppet-plugin.8 +1 -1
  127. data/man/man8/puppet-report.8 +4 -1
  128. data/man/man8/puppet-resource.8 +1 -1
  129. data/man/man8/puppet-script.8 +2 -2
  130. data/man/man8/puppet-ssl.8 +5 -1
  131. data/man/man8/puppet-status.8 +1 -1
  132. data/man/man8/puppet.8 +2 -2
  133. data/spec/fixtures/integration/application/agent/cached_deferred_catalog.json +91 -0
  134. data/spec/fixtures/ssl/127.0.0.1-key.pem +107 -57
  135. data/spec/fixtures/ssl/127.0.0.1.pem +52 -31
  136. data/spec/fixtures/ssl/bad-basic-constraints.pem +57 -35
  137. data/spec/fixtures/ssl/bad-int-basic-constraints.pem +57 -35
  138. data/spec/fixtures/ssl/ca.pem +57 -35
  139. data/spec/fixtures/ssl/crl.pem +28 -18
  140. data/spec/fixtures/ssl/ec-key.pem +11 -11
  141. data/spec/fixtures/ssl/ec.pem +33 -24
  142. data/spec/fixtures/ssl/encrypted-ec-key.pem +12 -12
  143. data/spec/fixtures/ssl/encrypted-key.pem +108 -58
  144. data/spec/fixtures/ssl/intermediate-agent-crl.pem +28 -19
  145. data/spec/fixtures/ssl/intermediate-agent.pem +57 -36
  146. data/spec/fixtures/ssl/intermediate-crl.pem +31 -21
  147. data/spec/fixtures/ssl/intermediate.pem +57 -36
  148. data/spec/fixtures/ssl/pluto-key.pem +107 -57
  149. data/spec/fixtures/ssl/pluto.pem +52 -30
  150. data/spec/fixtures/ssl/request-key.pem +107 -57
  151. data/spec/fixtures/ssl/request.pem +47 -26
  152. data/spec/fixtures/ssl/revoked-key.pem +107 -57
  153. data/spec/fixtures/ssl/revoked.pem +52 -30
  154. data/spec/fixtures/ssl/signed-key.pem +107 -57
  155. data/spec/fixtures/ssl/signed.pem +52 -30
  156. data/spec/fixtures/ssl/tampered-cert.pem +52 -30
  157. data/spec/fixtures/ssl/tampered-csr.pem +47 -26
  158. data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +107 -57
  159. data/spec/fixtures/ssl/unknown-127.0.0.1.pem +50 -29
  160. data/spec/fixtures/ssl/unknown-ca-key.pem +107 -57
  161. data/spec/fixtures/ssl/unknown-ca.pem +55 -33
  162. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services_vendor_preset +9 -0
  163. data/spec/fixtures/unit/provider/user/aix/aix_passwd_file.out +4 -0
  164. data/spec/integration/application/agent_spec.rb +160 -3
  165. data/spec/integration/application/apply_spec.rb +19 -0
  166. data/spec/integration/application/plugin_spec.rb +1 -1
  167. data/spec/integration/application/resource_spec.rb +30 -0
  168. data/spec/integration/defaults_spec.rb +0 -7
  169. data/spec/integration/environments/setting_hooks_spec.rb +1 -1
  170. data/spec/integration/http/client_spec.rb +12 -0
  171. data/spec/integration/indirector/direct_file_server_spec.rb +1 -3
  172. data/spec/integration/resource/type_collection_spec.rb +2 -6
  173. data/spec/integration/transaction_spec.rb +4 -9
  174. data/spec/integration/util/windows/adsi_spec.rb +21 -1
  175. data/spec/integration/util/windows/principal_spec.rb +21 -0
  176. data/spec/integration/util/windows/registry_spec.rb +6 -10
  177. data/spec/lib/puppet/test_ca.rb +2 -2
  178. data/spec/lib/puppet_spec/settings.rb +6 -1
  179. data/spec/spec_helper.rb +12 -5
  180. data/spec/unit/agent_spec.rb +8 -6
  181. data/spec/unit/application/agent_spec.rb +7 -3
  182. data/spec/unit/application/config_spec.rb +224 -4
  183. data/spec/unit/application/facts_spec.rb +482 -3
  184. data/spec/unit/application/filebucket_spec.rb +0 -2
  185. data/spec/unit/application/ssl_spec.rb +23 -0
  186. data/spec/unit/application_spec.rb +51 -9
  187. data/spec/unit/configurer/downloader_spec.rb +6 -0
  188. data/spec/unit/configurer_spec.rb +23 -0
  189. data/spec/unit/confine/feature_spec.rb +1 -1
  190. data/spec/unit/confine_spec.rb +8 -2
  191. data/spec/unit/defaults_spec.rb +36 -1
  192. data/spec/unit/environments_spec.rb +221 -68
  193. data/spec/unit/face/config_spec.rb +27 -32
  194. data/spec/unit/face/facts_spec.rb +4 -0
  195. data/spec/unit/face/node_spec.rb +0 -11
  196. data/spec/unit/file_serving/configuration/parser_spec.rb +0 -1
  197. data/spec/unit/file_serving/fileset_spec.rb +60 -0
  198. data/spec/unit/file_serving/metadata_spec.rb +3 -3
  199. data/spec/unit/file_serving/terminus_helper_spec.rb +11 -4
  200. data/spec/unit/file_system_spec.rb +9 -0
  201. data/spec/unit/forge/module_release_spec.rb +2 -7
  202. data/spec/unit/functions/inline_epp_spec.rb +26 -1
  203. data/spec/unit/gettext/config_spec.rb +12 -0
  204. data/spec/unit/http/service/compiler_spec.rb +172 -0
  205. data/spec/unit/http/service_spec.rb +1 -1
  206. data/spec/unit/indirector/catalog/compiler_spec.rb +14 -10
  207. data/spec/unit/indirector/face_spec.rb +0 -1
  208. data/spec/unit/indirector/facts/facter_spec.rb +95 -1
  209. data/spec/unit/indirector/facts/json_spec.rb +255 -0
  210. data/spec/unit/indirector/file_bucket_file/selector_spec.rb +26 -8
  211. data/spec/unit/indirector/indirection_spec.rb +8 -12
  212. data/spec/unit/indirector/key/file_spec.rb +0 -1
  213. data/spec/unit/indirector/node/json_spec.rb +33 -0
  214. data/spec/{integration/indirector/report/yaml.rb → unit/indirector/report/json_spec.rb} +13 -24
  215. data/spec/unit/indirector/report/yaml_spec.rb +72 -8
  216. data/spec/unit/indirector_spec.rb +2 -2
  217. data/spec/unit/module_tool/applications/installer_spec.rb +66 -0
  218. data/spec/unit/network/authconfig_spec.rb +0 -3
  219. data/spec/unit/network/formats_spec.rb +41 -0
  220. data/spec/unit/network/http/api/indirected_routes_spec.rb +0 -9
  221. data/spec/unit/network/http/factory_spec.rb +19 -0
  222. data/spec/unit/network/http/handler_spec.rb +0 -5
  223. data/spec/unit/parser/compiler_spec.rb +3 -19
  224. data/spec/unit/parser/functions/fqdn_rand_spec.rb +15 -1
  225. data/spec/unit/parser/resource_spec.rb +14 -8
  226. data/spec/unit/parser/templatewrapper_spec.rb +4 -3
  227. data/spec/unit/pops/evaluator/deferred_resolver_spec.rb +20 -0
  228. data/spec/unit/pops/types/p_sem_ver_type_spec.rb +18 -0
  229. data/spec/unit/pops/types/p_sensitive_type_spec.rb +18 -0
  230. data/spec/unit/property_spec.rb +1 -0
  231. data/spec/unit/provider/group/groupadd_spec.rb +5 -2
  232. data/spec/unit/provider/nameservice_spec.rb +66 -65
  233. data/spec/unit/provider/package/apt_spec.rb +28 -23
  234. data/spec/unit/provider/package/aptitude_spec.rb +1 -1
  235. data/spec/unit/provider/package/base_spec.rb +6 -5
  236. data/spec/unit/provider/package/dnfmodule_spec.rb +10 -1
  237. data/spec/unit/provider/package/nim_spec.rb +42 -0
  238. data/spec/unit/provider/package/pacman_spec.rb +18 -12
  239. data/spec/unit/provider/package/pip_spec.rb +6 -11
  240. data/spec/unit/provider/package/pkgdmg_spec.rb +0 -4
  241. data/spec/unit/provider/service/init_spec.rb +1 -0
  242. data/spec/unit/provider/service/openwrt_spec.rb +3 -1
  243. data/spec/unit/provider/service/systemd_spec.rb +53 -8
  244. data/spec/unit/provider/service/windows_spec.rb +202 -0
  245. data/spec/unit/provider/user/aix_spec.rb +5 -0
  246. data/spec/unit/provider/user/directoryservice_spec.rb +67 -35
  247. data/spec/unit/provider/user/hpux_spec.rb +1 -1
  248. data/spec/unit/provider/user/pw_spec.rb +2 -0
  249. data/spec/unit/provider/user/useradd_spec.rb +71 -3
  250. data/spec/unit/provider_spec.rb +8 -10
  251. data/spec/unit/puppet_pal_catalog_spec.rb +45 -0
  252. data/spec/unit/resource/capability_finder_spec.rb +6 -1
  253. data/spec/unit/resource/catalog_spec.rb +1 -1
  254. data/spec/unit/resource/type_spec.rb +1 -1
  255. data/spec/unit/resource_spec.rb +11 -10
  256. data/spec/unit/settings_spec.rb +419 -242
  257. data/spec/unit/ssl/base_spec.rb +0 -1
  258. data/spec/unit/ssl/host_spec.rb +0 -5
  259. data/spec/unit/ssl/ssl_provider_spec.rb +14 -8
  260. data/spec/unit/ssl/state_machine_spec.rb +19 -5
  261. data/spec/unit/transaction/additional_resource_generator_spec.rb +3 -9
  262. data/spec/unit/transaction/event_manager_spec.rb +14 -11
  263. data/spec/unit/transaction_spec.rb +18 -11
  264. data/spec/unit/type/file/content_spec.rb +0 -1
  265. data/spec/unit/type/file/selinux_spec.rb +3 -5
  266. data/spec/unit/type/file_spec.rb +0 -6
  267. data/spec/unit/type/group_spec.rb +13 -6
  268. data/spec/unit/type/resources_spec.rb +7 -7
  269. data/spec/unit/type/service_spec.rb +60 -189
  270. data/spec/unit/type/tidy_spec.rb +17 -8
  271. data/spec/unit/type/user_spec.rb +45 -0
  272. data/spec/unit/type_spec.rb +2 -2
  273. data/spec/unit/util/at_fork_spec.rb +2 -2
  274. data/spec/unit/util/autoload_spec.rb +5 -1
  275. data/spec/unit/util/backups_spec.rb +1 -2
  276. data/spec/unit/util/execution_spec.rb +15 -11
  277. data/spec/unit/util/inifile_spec.rb +6 -14
  278. data/spec/unit/util/log_spec.rb +8 -7
  279. data/spec/unit/util/logging_spec.rb +3 -3
  280. data/spec/unit/util/posix_spec.rb +363 -15
  281. data/spec/unit/util/rubygems_spec.rb +2 -2
  282. data/spec/unit/util/selinux_spec.rb +163 -68
  283. data/spec/unit/util/storage_spec.rb +3 -1
  284. data/spec/unit/util/suidmanager_spec.rb +44 -41
  285. data/spec/unit/util/windows/sid_spec.rb +6 -0
  286. data/spec/unit/util_spec.rb +13 -6
  287. data/tasks/generate_cert_fixtures.rake +2 -2
  288. metadata +25 -14
  289. data/spec/integration/application/config_spec.rb +0 -74
  290. data/spec/lib/matchers/include.rb +0 -27
  291. data/spec/lib/matchers/include_spec.rb +0 -32
  292. data/spec/unit/face/catalog_spec.rb +0 -6
  293. data/spec/unit/face/module_spec.rb +0 -3
@@ -50,7 +50,7 @@ class Puppet::Parser::TemplateWrapper
50
50
  # @return [Array<String>] The tags defined in the current scope
51
51
  # @api public
52
52
  def tags
53
- scope.tags
53
+ raise NotImplementedError, "Call 'all_tags' instead."
54
54
  end
55
55
 
56
56
  # @return [Array<String>] All the defined tags
@@ -16,10 +16,12 @@ class DeferredResolver
16
16
  #
17
17
  # @param facts [Puppet::Node::Facts] the facts object for the node
18
18
  # @param catalog [Puppet::Resource::Catalog] the catalog where all deferred values should be replaced
19
+ # @param environment [Puppet::Node::Environment] the environment whose anonymous module methods
20
+ # are to be mixed into the scope
19
21
  # @return [nil] does not return anything - the catalog is modified as a side effect
20
22
  #
21
- def self.resolve_and_replace(facts, catalog)
22
- compiler = Puppet::Parser::ScriptCompiler.new(catalog.environment_instance, catalog.name, true)
23
+ def self.resolve_and_replace(facts, catalog, environment = catalog.environment_instance)
24
+ compiler = Puppet::Parser::ScriptCompiler.new(environment, catalog.name, true)
23
25
  resolver = new(compiler)
24
26
  resolver.set_facts_variable(facts)
25
27
  # TODO:
@@ -108,7 +110,7 @@ class DeferredResolver
108
110
  # If any of the arguments to a future is a future it needs to be resolved first
109
111
  func_name = f.name
110
112
  mapped_arguments = map_arguments(f.arguments)
111
- # if name starts with $ then this is a call to dig
113
+ # if name starts with $ then this is a call to dig
112
114
  if func_name[0] == DOLLAR
113
115
  var_name = func_name[1..-1]
114
116
  func_name = DIG
@@ -462,10 +462,24 @@ class EvaluatorImpl
462
462
  end
463
463
 
464
464
  def eval_EppExpression(o, scope)
465
+ contains_sensitive = false
466
+
465
467
  scope["@epp"] = []
466
468
  evaluate(o.body, scope)
467
- result = scope["@epp"].join
468
- result
469
+ result = scope["@epp"].map do |r|
470
+ if r.instance_of?(Puppet::Pops::Types::PSensitiveType::Sensitive)
471
+ contains_sensitive = true
472
+ string(r.unwrap, scope)
473
+ else
474
+ r
475
+ end
476
+ end.join
477
+
478
+ if contains_sensitive
479
+ Puppet::Pops::Types::PSensitiveType::Sensitive.new(result)
480
+ else
481
+ result
482
+ end
469
483
  end
470
484
 
471
485
  def eval_RenderStringExpression(o, scope)
@@ -474,7 +488,12 @@ class EvaluatorImpl
474
488
  end
475
489
 
476
490
  def eval_RenderExpression(o, scope)
477
- scope["@epp"] << string(evaluate(o.expr, scope), scope)
491
+ result = evaluate(o.expr, scope)
492
+ if result.instance_of?(Puppet::Pops::Types::PSensitiveType::Sensitive)
493
+ scope["@epp"] << result
494
+ else
495
+ scope["@epp"] << string(result, scope)
496
+ end
478
497
  nil
479
498
  end
480
499
 
@@ -31,7 +31,7 @@ class Puppet::Pops::Model::AstTransformer
31
31
  def ast(o, klass, hash={})
32
32
  # create and pass hash with file and line information
33
33
  # PUP-3274 - still needed since hostname transformation requires AST::HostName, and AST::Regexp
34
- klass.new(merge_location(hash, o))
34
+ klass.new(**merge_location(hash, o))
35
35
  end
36
36
 
37
37
  # THIS IS AN EXPENSIVE OPERATION
@@ -95,16 +95,22 @@ class PSemVerType < PScalarType
95
95
  end
96
96
 
97
97
  def from_args(major, minor, patch, prerelease = nil, build = nil)
98
- SemanticPuppet::Version.new(major, minor, patch, prerelease, build)
98
+ SemanticPuppet::Version.new(major, minor, patch, to_array(prerelease), to_array(build))
99
99
  end
100
100
 
101
101
  def from_hash(hash)
102
- SemanticPuppet::Version.new(hash['major'], hash['minor'], hash['patch'], hash['prerelease'], hash['build'])
102
+ SemanticPuppet::Version.new(hash['major'], hash['minor'], hash['patch'], to_array(hash['prerelease']), to_array(hash['build']))
103
103
  end
104
104
 
105
105
  def on_error(str)
106
106
  _("The string '%{str}' cannot be converted to a SemVer") % { str: str }
107
107
  end
108
+
109
+ private
110
+
111
+ def to_array(component)
112
+ component ? [component] : nil
113
+ end
108
114
  end
109
115
  end
110
116
 
@@ -24,6 +24,16 @@ class PSensitiveType < PTypeWithContainedType
24
24
  def inspect
25
25
  "#<#{self}>"
26
26
  end
27
+
28
+ def hash
29
+ @value.hash
30
+ end
31
+
32
+ def ==(other)
33
+ other.is_a?(Sensitive) &&
34
+ other.hash == hash
35
+ end
36
+ alias eql? ==
27
37
  end
28
38
 
29
39
  def self.register_ptype(loader, ir)
@@ -47,7 +47,7 @@ module Puppet
47
47
  #ok, some 'convention' if the list property is named groups, provider should implement a groups method
48
48
  tmp = provider.send(name) if provider
49
49
  if tmp && tmp != :absent
50
- return tmp.split(delimiter)
50
+ return tmp.instance_of?(Array) ? tmp : tmp.split(delimiter)
51
51
  else
52
52
  return :absent
53
53
  end
@@ -130,16 +130,21 @@ Puppet::Type.type(:group).provide :groupadd, :parent => Puppet::Provider::NameSe
130
130
  private
131
131
 
132
132
  def findgroup(key, value)
133
- group_file = "/etc/group"
133
+ group_file = '/etc/group'
134
134
  group_keys = [:group_name, :password, :gid, :user_list]
135
- index = group_keys.index(key)
136
- @group_content ||= File.read(group_file)
137
- @group_content.each_line do |line|
138
- group = line.split(":")
139
- if group[index] == value
140
- return Hash[group_keys.zip(group)]
135
+
136
+ unless @groups
137
+ unless Puppet::FileSystem.exist?(group_file)
138
+ raise Puppet::Error.new("Forcelocal set for group resource '#{resource[:name]}', but #{group_file} does not exist")
139
+ end
140
+
141
+ @groups = []
142
+ Puppet::FileSystem.each_line(group_file) do |line|
143
+ group = line.chomp.split(':')
144
+ @groups << Hash[group_keys.zip(group)]
141
145
  end
142
146
  end
143
- false
147
+
148
+ @groups.find { |param| param[key] == value } || false
144
149
  end
145
150
  end
@@ -42,7 +42,11 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
42
42
 
43
43
  def query
44
44
  hash = super
45
- hash[:mark] = :manual if aptmark('showmanual').split("\n").include?(@resource[:name])
45
+
46
+ if !%i(absent purged).include?(hash[:ensure]) && aptmark('showmanual', @resource[:name]).strip == @resource[:name]
47
+ hash[:mark] = :manual
48
+ end
49
+
46
50
  hash
47
51
  end
48
52
 
@@ -51,6 +55,10 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
51
55
  @property_flush = {}
52
56
  end
53
57
 
58
+ def mark
59
+ @property_flush[:mark]
60
+ end
61
+
54
62
  def mark=(value)
55
63
  @property_flush[:mark] = value
56
64
  end
@@ -143,7 +151,13 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
143
151
  end
144
152
 
145
153
  cmd += install_options if @resource[:install_options]
146
- cmd << :install << str
154
+ cmd << :install
155
+
156
+ if source
157
+ cmd << source
158
+ else
159
+ cmd << str
160
+ end
147
161
 
148
162
  self.unhold if self.properties[:mark] == :hold
149
163
  begin
@@ -151,6 +165,18 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
151
165
  ensure
152
166
  self.hold if @resource[:mark] == :hold
153
167
  end
168
+
169
+ # If a source file was specified, we must make sure the expected version was installed from specified file
170
+ if source && !%i(present installed).include?(should)
171
+ is = self.query
172
+ raise Puppet::Error, _("Could not find package %{name}") % { name: self.name } unless is
173
+
174
+ version = is[:ensure]
175
+
176
+ raise Puppet::Error, _("Failed to update to version %{should}, got version %{version} instead") % { should: should, version: version } unless
177
+ insync?(version)
178
+ end
179
+
154
180
  end
155
181
 
156
182
  # What's the latest package version available?
@@ -227,4 +253,10 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
227
253
  end
228
254
  should_range.include?(is_version)
229
255
  end
256
+
257
+ private
258
+
259
+ def source
260
+ @source ||= @resource[:source]
261
+ end
230
262
  end
@@ -26,4 +26,10 @@ Puppet::Type.type(:package).provide :aptitude, :parent => :apt, :source => :dpkg
26
26
  def purge
27
27
  aptitude '-y', 'purge', @resource[:name]
28
28
  end
29
+
30
+ private
31
+
32
+ def source
33
+ nil
34
+ end
29
35
  end
@@ -93,7 +93,7 @@ Puppet::Type.type(:package).provide :dnfmodule, :parent => :dnf do
93
93
  # module has no default profile and no profile was requested, so just enable the stream
94
94
  # DNF versions prior to 4.2.8 do not need this workaround
95
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])}$/
96
+ if @resource[:flavor] == nil && e.message =~ /^(?:missing|broken) groups or modules: #{Regexp.quote(@resource[:name])}$/
97
97
  enable(args)
98
98
  else
99
99
  raise
@@ -154,20 +154,25 @@ Puppet::Type.type(:package).provide :nim, :parent => :aix, :source => :aix do
154
154
  # I spent a lot of time trying to figure out a solution that didn't
155
155
  # require parsing the `nimclient -o showres` output and was unable to
156
156
  # do so.
157
- self::HEADER_LINE_REGEX = /^([^\s]+)\s+[^@]+@@(I|R):(\1)\s+[^\s]+$/
158
- self::PACKAGE_LINE_REGEX = /^.*@@(I|R):(.*)$/
159
- self::RPM_PACKAGE_REGEX = /^(.*)-(.*-\d+) \2$/
157
+ self::HEADER_LINE_REGEX = /^([^\s]+)\s+[^@]+@@(I|R|S):(\1)\s+[^\s]+$/
158
+ self::PACKAGE_LINE_REGEX = /^.*@@(I|R|S):(.*)$/
159
+ self::RPM_PACKAGE_REGEX = /^(.*)-(.*-\d+\w*) \2$/
160
160
  self::INSTALLP_PACKAGE_REGEX = /^(.*) (.*)$/
161
161
 
162
162
  # Here is some sample output that shows what the above regexes will be up
163
163
  # against:
164
- # FOR AN INSTALLP PACKAGE:
164
+ # FOR AN INSTALLP(bff) PACKAGE:
165
165
  #
166
166
  # mypackage.foo ALL @@I:mypackage.foo _all_filesets
167
- # @ 1.2.3.1 MyPackage Runtime Environment @@I:mypackage.foo 1.2.3.1
168
167
  # + 1.2.3.4 MyPackage Runtime Environment @@I:mypackage.foo 1.2.3.4
169
168
  # + 1.2.3.8 MyPackage Runtime Environment @@I:mypackage.foo 1.2.3.8
170
169
  #
170
+ # FOR AN INSTALLP(bff) PACKAGE with security update:
171
+ #
172
+ # bos.net ALL @@S:bos.net _all_filesets
173
+ # + 7.2.0.1 TCP/IP ntp Applications @@S:bos.net.tcp.ntp 7.2.0.1
174
+ # + 7.2.0.2 TCP/IP ntp Applications @@S:bos.net.tcp.ntp 7.2.0.2
175
+ #
171
176
  # FOR AN RPM PACKAGE:
172
177
  #
173
178
  # mypackage.foo ALL @@R:mypackage.foo _all_filesets
@@ -243,7 +248,7 @@ Puppet::Type.type(:package).provide :nim, :parent => :aix, :source => :aix do
243
248
  package_string = match.captures[1]
244
249
 
245
250
  case package_type_flag
246
- when "I"
251
+ when "I","S"
247
252
  parse_installp_package_string(package_string)
248
253
  when "R"
249
254
  parse_rpm_package_string(package_string)
@@ -17,6 +17,8 @@ Puppet::Type.type(:service).provide :debian, :parent => :init do
17
17
  commands :invoke_rc => "/usr/sbin/invoke-rc.d"
18
18
  commands :service => "/usr/sbin/service"
19
19
 
20
+ confine :false => Puppet::FileSystem.exist?('/proc/1/comm') && Puppet::FileSystem.read('/proc/1/comm').include?('systemd')
21
+
20
22
  defaultfor :operatingsystem => :cumuluslinux, :operatingsystemmajrelease => ['1','2']
21
23
  defaultfor :operatingsystem => :debian, :operatingsystemmajrelease => ['5','6','7']
22
24
  defaultfor :operatingsystem => :devuan
@@ -30,7 +30,7 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do
30
30
  def self.instances
31
31
  i = []
32
32
  output = systemctl('list-unit-files', '--type', 'service', '--full', '--all', '--no-pager')
33
- output.scan(/^(\S+)\s+(disabled|enabled|masked|indirect|bad|static)\s*$/i).each do |m|
33
+ output.scan(/^(\S+)\s+(disabled|enabled|masked|indirect|bad|static)\s*([^-]\S+)?\s*$/i).each do |m|
34
34
  Puppet.debug("#{m[0]} marked as bad by `systemctl`. It is recommended to be further checked.") if m[1] == "bad"
35
35
  i << new(:name => m[0])
36
36
  end
@@ -45,8 +45,13 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do
45
45
  def enabled_insync?(current)
46
46
  case cached_enabled?[:output]
47
47
  when 'static'
48
- Puppet.debug("Unable to enable or disable static service #{@resource[:name]}")
49
- return true
48
+ # masking static services is OK, but enabling/disabling them is not
49
+ if @resource[:enable] == :mask
50
+ current == @resource[:enable]
51
+ else
52
+ Puppet.debug("Unable to enable or disable static service #{@resource[:name]}")
53
+ return true
54
+ end
50
55
  when 'indirect'
51
56
  Puppet.debug("Service #{@resource[:name]} is in 'indirect' state and cannot be enabled/disabled")
52
57
  return true
@@ -159,10 +164,15 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do
159
164
  end
160
165
 
161
166
  def mask
162
- self.disable
167
+ disable if exist?
163
168
  systemctl_change_enable(:mask)
164
169
  end
165
170
 
171
+ def exist?
172
+ result = execute([command(:systemctl), 'cat', '--', @resource[:name]], :failonfail => false)
173
+ result.exitstatus == 0
174
+ end
175
+
166
176
  def unmask
167
177
  systemctl_change_enable(:unmask)
168
178
  end
@@ -128,17 +128,55 @@ Puppet::Type.type(:service).provide :windows, :parent => :service do
128
128
  services
129
129
  end
130
130
 
131
+ def logonaccount_insync?(current)
132
+ @normalized_logon_account ||= normalize_logonaccount
133
+ @resource[:logonaccount] = @normalized_logon_account
134
+
135
+ insync = @resource[:logonaccount] == current
136
+ self.logonpassword = @resource[:logonpassword] if insync
137
+ insync
138
+ end
139
+
131
140
  def logonaccount
132
141
  return unless Puppet::Util::Windows::Service.exists?(@resource[:name])
133
142
  Puppet::Util::Windows::Service.logon_account(@resource[:name])
134
143
  end
135
144
 
136
145
  def logonaccount=(value)
146
+ validate_logon_credentials
137
147
  Puppet::Util::Windows::Service.set_startup_configuration(@resource[:name], options: {logon_account: value, logon_password: @resource[:logonpassword]})
138
148
  restart if @resource[:ensure] == :running && [:running, :paused].include?(status)
139
149
  end
140
150
 
141
151
  def logonpassword=(value)
152
+ validate_logon_credentials
142
153
  Puppet::Util::Windows::Service.set_startup_configuration(@resource[:name], options: {logon_password: value})
143
154
  end
155
+
156
+ private
157
+
158
+ def normalize_logonaccount
159
+ logon_account = @resource[:logonaccount].sub(/^\.\\/, "#{Puppet::Util::Windows::ADSI.computer_name}\\")
160
+ return 'LocalSystem' if Puppet::Util::Windows::User::localsystem?(logon_account)
161
+
162
+ @logonaccount_information ||= Puppet::Util::Windows::SID.name_to_principal(logon_account)
163
+ return logon_account unless @logonaccount_information
164
+ return ".\\#{@logonaccount_information.account}" if @logonaccount_information.domain == Puppet::Util::Windows::ADSI.computer_name
165
+ @logonaccount_information.domain_account
166
+ end
167
+
168
+ def validate_logon_credentials
169
+ unless Puppet::Util::Windows::User::localsystem?(@normalized_logon_account)
170
+ raise Puppet::Error.new("\"#{@normalized_logon_account}\" is not a valid account") unless @logonaccount_information && [:SidTypeUser, :SidTypeWellKnownGroup].include?(@logonaccount_information.account_type)
171
+
172
+ user_rights = Puppet::Util::Windows::User::get_rights(@logonaccount_information.domain_account) unless Puppet::Util::Windows::User::default_system_account?(@normalized_logon_account)
173
+ raise Puppet::Error.new("\"#{@normalized_logon_account}\" has the 'Log On As A Service' right set to denied.") if user_rights =~ /SeDenyServiceLogonRight/
174
+ raise Puppet::Error.new("\"#{@normalized_logon_account}\" is missing the 'Log On As A Service' right.") unless user_rights.nil? || user_rights =~ /SeServiceLogonRight/
175
+ end
176
+
177
+ is_a_predefined_local_account = Puppet::Util::Windows::User::default_system_account?(@normalized_logon_account) || @normalized_logon_account == 'LocalSystem'
178
+ account_info = @normalized_logon_account.split("\\")
179
+ able_to_logon = Puppet::Util::Windows::User.password_is?(account_info[1], @resource[:logonpassword], account_info[0]) unless is_a_predefined_local_account
180
+ raise Puppet::Error.new("The given password is invalid for user '#{@normalized_logon_account}'.") unless is_a_predefined_local_account || able_to_logon
181
+ end
144
182
  end
@@ -178,7 +178,7 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
178
178
  # does not have a password.
179
179
  break if line =~ /^\S+:$/
180
180
 
181
- match_obj = /password = (\S+)/.match(line)
181
+ match_obj = /password\s+=\s+(\S+)/.match(line)
182
182
  end
183
183
  return :absent unless match_obj
184
184
 
@@ -211,7 +211,7 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
211
211
  tempfile = Tempfile.new("puppet_#{user}_pw", :encoding => Encoding::ASCII)
212
212
  tempfile << "#{user}:#{value}\n"
213
213
  tempfile.close()
214
-
214
+
215
215
  # Options '-e', '-c', use encrypted password and clear flags
216
216
  # Must receive "user:enc_password" as input
217
217
  # command, arguments = {:failonfail => true, :combine => true}
@@ -435,7 +435,7 @@ Puppet::Type.type(:user).provide :directoryservice do
435
435
  ['home', 'uid', 'gid', 'comment', 'shell'].each do |setter_method|
436
436
  define_method("#{setter_method}=") do |value|
437
437
  if @property_hash[setter_method.intern]
438
- if self.class.get_os_version.split('.').last.to_i >= 14 && %w(home uid).include?(setter_method)
438
+ if %w(home uid).include?(setter_method)
439
439
  raise Puppet::Error, "OS X version #{self.class.get_os_version} does not allow changing #{setter_method} using puppet"
440
440
  end
441
441
  begin
@@ -536,6 +536,14 @@ Puppet::Type.type(:user).provide :directoryservice do
536
536
  if (shadow_hash_data.class == Hash) && (shadow_hash_data.has_key?('SALTED-SHA512'))
537
537
  shadow_hash_data.delete('SALTED-SHA512')
538
538
  end
539
+
540
+ # Starting with macOS 11 Big Sur, the AuthenticationAuthority field
541
+ # could be missing entirely and without it the managed user cannot log in
542
+ if needs_sha512_pbkdf2_authentication_authority_to_be_added?(users_plist)
543
+ Puppet.debug("Adding 'SALTED-SHA512-PBKDF2' AuthenticationAuthority key for ShadowHash to user '#{@resource.name}'")
544
+ merge_attribute_with_dscl('Users', @resource.name, 'AuthenticationAuthority', ERB::Util.html_escape(SHA512_PBKDF2_AUTHENTICATION_AUTHORITY))
545
+ end
546
+
539
547
  set_salted_pbkdf2(users_plist, shadow_hash_data, 'entropy', value)
540
548
  end
541
549
  end
@@ -562,6 +570,17 @@ Puppet::Type.type(:user).provide :directoryservice do
562
570
  end
563
571
  end
564
572
 
573
+ # This method will check if authentication_authority key of a user's plist
574
+ # needs SALTED_SHA512_PBKDF2 to be added. This is a valid case for macOS 11 (Big Sur)
575
+ # where users created with `dscl` started to have this field missing
576
+ def needs_sha512_pbkdf2_authentication_authority_to_be_added?(users_plist)
577
+ authority = users_plist['authentication_authority']
578
+ return false if Puppet::Util::Package.versioncmp(self.class.get_os_version, '11.0.0') < 0 && authority && authority.include?(SHA512_PBKDF2_AUTHENTICATION_AUTHORITY)
579
+
580
+ Puppet.debug("User '#{@resource.name}' is missing the 'SALTED-SHA512-PBKDF2' AuthenticationAuthority key for ShadowHash")
581
+ true
582
+ end
583
+
565
584
  # This method will embed the binary plist data comprising the user's
566
585
  # password hash (and Salt/Iterations value if the OS is 10.8 or greater)
567
586
  # into the ShadowHashData key of the user's plist.
@@ -572,11 +591,7 @@ Puppet::Type.type(:user).provide :directoryservice do
572
591
  else
573
592
  users_plist['ShadowHashData'] = [binary_plist]
574
593
  end
575
- if Puppet::Util::Package.versioncmp(self.class.get_os_version, '10.15') < 0
576
- write_users_plist_to_disk(users_plist)
577
- else
578
- write_and_import_shadow_hash_data(users_plist['ShadowHashData'].first)
579
- end
594
+ write_and_import_shadow_hash_data(users_plist['ShadowHashData'].first)
580
595
  end
581
596
 
582
597
  # This method writes the ShadowHashData plist in a temporary file,
@@ -652,12 +667,6 @@ Puppet::Type.type(:user).provide :directoryservice do
652
667
  set_shadow_hash_data(users_plist, binary_plist)
653
668
  end
654
669
 
655
- # This method will accept a plist in XML format, save it to disk, convert
656
- # the plist to a binary format, and flush the dscl cache.
657
- def write_users_plist_to_disk(users_plist)
658
- Puppet::Util::Plist.write_plist_file(users_plist, "#{users_plist_dir}/#{@resource.name}.plist", :binary)
659
- end
660
-
661
670
  # This is a simple wrapper method for writing values to a file.
662
671
  def write_to_file(filename, value)
663
672
  Puppet.deprecation_warning("Puppet::Type.type(:user).provider(:directoryservice).write_to_file is deprecated and will be removed in Puppet 5.")
@@ -667,4 +676,8 @@ Puppet::Type.type(:user).provide :directoryservice do
667
676
  raise Puppet::Error, "Could not write to file #{filename}: #{detail}", detail.backtrace
668
677
  end
669
678
  end
679
+
680
+ private
681
+
682
+ SHA512_PBKDF2_AUTHENTICATION_AUTHORITY = ';ShadowHash;HASHLIST:<SALTED-SHA512-PBKDF2,SRP-RFC5054-4096-SHA512-PBKDF2>'
670
683
  end