chef 16.14.1-universal-mingw32 → 16.17.4-universal-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef/action_collection.rb +1 -1
  3. data/lib/chef/application.rb +1 -1
  4. data/lib/chef/cookbook_version.rb +26 -4
  5. data/lib/chef/data_collector/run_end_message.rb +2 -2
  6. data/lib/chef/deprecated.rb +14 -4
  7. data/lib/chef/exceptions.rb +3 -0
  8. data/lib/chef/formatters/error_mapper.rb +2 -2
  9. data/lib/chef/http.rb +5 -5
  10. data/lib/chef/knife/bootstrap.rb +1 -1
  11. data/lib/chef/node.rb +20 -19
  12. data/lib/chef/policy_builder/policyfile.rb +5 -0
  13. data/lib/chef/provider/group/dscl.rb +1 -1
  14. data/lib/chef/provider/package/powershell.rb +5 -0
  15. data/lib/chef/provider/template/content.rb +1 -1
  16. data/lib/chef/resource/chef_client_trusted_certificate.rb +1 -0
  17. data/lib/chef/resource/homebrew_cask.rb +13 -7
  18. data/lib/chef/resource/mount.rb +1 -1
  19. data/lib/chef/resource/rhsm_subscription.rb +5 -5
  20. data/lib/chef/resource/support/client.erb +6 -0
  21. data/lib/chef/resource/systemd_unit.rb +1 -1
  22. data/lib/chef/resource/user_ulimit.rb +1 -0
  23. data/lib/chef/resource/windows_security_policy.rb +55 -39
  24. data/lib/chef/resource/windows_uac.rb +3 -1
  25. data/lib/chef/resource/windows_user_privilege.rb +1 -1
  26. data/lib/chef/resource.rb +1 -1
  27. data/lib/chef/resource_reporter.rb +1 -1
  28. data/lib/chef/shell/ext.rb +3 -3
  29. data/lib/chef/version.rb +1 -1
  30. data/lib/chef/win32/api.rb +9 -2
  31. data/lib/chef/win32/version.rb +2 -1
  32. data/spec/functional/resource/group_spec.rb +5 -1
  33. data/spec/functional/resource/link_spec.rb +8 -0
  34. data/spec/integration/knife/delete_spec.rb +1 -1
  35. data/spec/integration/knife/download_spec.rb +2 -2
  36. data/spec/integration/knife/upload_spec.rb +5 -6
  37. data/spec/unit/cookbook_version_spec.rb +52 -0
  38. data/spec/unit/data_collector_spec.rb +71 -2
  39. data/spec/unit/policy_builder/policyfile_spec.rb +11 -1
  40. data/spec/unit/provider/package/powershell_spec.rb +74 -12
  41. data/spec/unit/resource/chef_client_trusted_certificate_spec.rb +14 -0
  42. data/spec/unit/resource/homebrew_cask_spec.rb +29 -11
  43. data/spec/unit/resource/mount_spec.rb +10 -0
  44. data/spec/unit/resource/rhsm_subscription_spec.rb +50 -3
  45. data/spec/unit/resource/systemd_unit_spec.rb +1 -1
  46. data/spec/unit/resource/user_ulimit_spec.rb +14 -1
  47. data/spec/unit/resource_spec.rb +5 -0
  48. metadata +6 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 33a8597bec6968b59ce9584a978aebd74196fb0fea365d5a3fffbc8fa195b717
4
- data.tar.gz: 606d5d67f32d6ce2a1a51f0c743635409d617363ddbdf4246fdc892eb6f3f586
3
+ metadata.gz: 89904622cc4db2281cdad6b5c8927c622fdc1997f73d232cd5c9e10f8ad68ba9
4
+ data.tar.gz: d9ded46dc296fc32c9478e74636d5241a31735923be4c73b29bb668c56312c48
5
5
  SHA512:
6
- metadata.gz: 82a2de26a728c8f057a2d9ae6c7372249978ed035a5478e91b6c11d92466ef045a4e37cbe9eb28cca1b4da84bff480b7b1029b239a4e5b1724df8c4edcbcb781
7
- data.tar.gz: c1a06f496a2e4b2f9c8d3e7b4bd012e446ac1b6b5952ae2381802b3354b2a8ee3f7700cc1a30ea8569068992f15b52a39b025495d631b7d8fb1cf977138dc088
6
+ metadata.gz: ba2d1c45cd1a2a121b23b04a8cd1e0b252567fe89c59eacbe60e7ceb0e89dc9690985b1a40662ec6db09124fec28f4ec65464f328c3605cd063ba3864518ba7f
7
+ data.tar.gz: 7d449a3247ca722cdf295c3c097933e7412942a5ded946ac3d1f8907d2703685f1439c75537655b280d4911a9dd1b4cdbb824f4a03428e2b68884d96e6b02960
@@ -128,7 +128,7 @@ class Chef
128
128
  #
129
129
  def cookbook_compilation_start(run_context)
130
130
  run_context.action_collection = self
131
- # fire the action_colleciton_registration hook after cookbook_compilation_start -- last chance for consumers to register
131
+ # fire the action_collection_registration hook after cookbook_compilation_start -- last chance for consumers to register
132
132
  run_context.events.enqueue(:action_collection_registration, self)
133
133
  @run_context = run_context
134
134
  end
@@ -310,7 +310,7 @@ class Chef
310
310
  logger.info "Forking #{ChefUtils::Dist::Infra::PRODUCT} instance to converge..."
311
311
  pid = fork do
312
312
  # Want to allow forked processes to finish converging when
313
- # TERM singal is received (exit gracefully)
313
+ # TERM signal is received (exit gracefully)
314
314
  trap("TERM") do
315
315
  logger.debug("SIGTERM received during converge," +
316
316
  " finishing converge to exit normally (send SIGINT to terminate immediately)")
@@ -138,11 +138,14 @@ class Chef
138
138
  end
139
139
 
140
140
  def recipe_yml_filenames_by_name
141
- @recipe_ym_filenames_by_name ||= begin
141
+ @recipe_yml_filenames_by_name ||= begin
142
142
  name_map = yml_filenames_by_name(files_for("recipes"))
143
- root_alias = cookbook_manifest.root_files.find { |record| record[:name] == "root_files/recipe.yml" }
143
+ root_alias = cookbook_manifest.root_files.find { |record|
144
+ record[:name] == "root_files/recipe.yml" ||
145
+ record[:name] == "root_files/recipe.yaml"
146
+ }
144
147
  if root_alias
145
- Chef::Log.error("Cookbook #{name} contains both recipe.yml and and recipes/default.yml, ignoring recipes/default.yml") if name_map["default"]
148
+ Chef::Log.error("Cookbook #{name} contains both recipe.yml and recipes/default.yml, ignoring recipes/default.yml") if name_map["default"]
146
149
  name_map["default"] = root_alias[:full_path]
147
150
  end
148
151
  name_map
@@ -582,8 +585,27 @@ class Chef
582
585
  records.select { |record| record[:name] =~ /\.rb$/ }.inject({}) { |memo, record| memo[File.basename(record[:name], ".rb")] = record[:full_path]; memo }
583
586
  end
584
587
 
588
+ # Filters YAML files from the superset of provided files.
589
+ # Checks for duplicate basenames with differing extensions (eg yaml v yml)
590
+ # and raises error if any are detected.
591
+ # This prevents us from arbitrarily the ".yaml" or ".yml" version when both are present,
592
+ # because we don't know which is correct.
593
+ # This method runs in O(n^2) where N = number of yml files present. This number should be consistently
594
+ # low enough that there's no noticeable perf impact.
585
595
  def yml_filenames_by_name(records)
586
- records.select { |record| record[:name] =~ /\.yml$/ }.inject({}) { |memo, record| memo[File.basename(record[:name], ".yml")] = record[:full_path]; memo }
596
+ yml_files = records.select { |record| record[:name] =~ /\.(y[a]?ml)$/ }
597
+ result = yml_files.inject({}) do |acc, record|
598
+ filename = record[:name]
599
+ base_dup_name = File.join(File.dirname(filename), File.basename(filename, File.extname(filename)))
600
+ yml_files.each do |other|
601
+ if other[:name] =~ /#{(File.extname(filename) == ".yml") ? "#{base_dup_name}.yaml" : "#{base_dup_name}.yml"}$/
602
+ raise Chef::Exceptions::AmbiguousYAMLFile.new("Cookbook #{name}@#{version} contains ambiguous files: #{filename} and #{other[:name]}. Please update the cookbook to remove the incorrect file.")
603
+ end
604
+ end
605
+ acc[File.basename(record[:name], File.extname(record[:name]))] = record[:full_path]
606
+ acc
607
+ end
608
+ result
587
609
  end
588
610
 
589
611
  def file_vendor
@@ -51,7 +51,7 @@ class Chef
51
51
  "id" => run_status&.run_id,
52
52
  "message_version" => "1.1.0",
53
53
  "message_type" => "run_converge",
54
- "node" => node || {},
54
+ "node" => node&.data_for_save || {},
55
55
  "node_name" => node&.name || data_collector.node_name,
56
56
  "organization_name" => organization,
57
57
  "resources" => all_action_records(action_collection),
@@ -128,7 +128,7 @@ class Chef
128
128
 
129
129
  if new_resource.cookbook_name
130
130
  hash["cookbook_name"] = new_resource.cookbook_name
131
- hash["cookbook_version"] = new_resource.cookbook_version.version
131
+ hash["cookbook_version"] = new_resource.cookbook_version&.version
132
132
  hash["recipe_name"] = new_resource.recipe_name
133
133
  end
134
134
 
@@ -79,10 +79,12 @@ class Chef
79
79
  return true if location =~ /^(.*?):(\d+):in/ && begin
80
80
  # Don't buffer the whole file in memory, so read it one line at a time.
81
81
  line_no = $2.to_i
82
- location_file = ::File.open($1)
83
- (line_no - 1).times { location_file.readline } # Read all the lines we don't care about.
84
- relevant_line = location_file.readline
85
- relevant_line.match?(/#.*chef:silence_deprecation($|[^:]|:#{self.class.deprecation_key})/)
82
+ if File.exist?($1) # some stacktraces come from `eval` and not a file
83
+ location_file = ::File.open($1)
84
+ (line_no - 1).times { location_file.readline } # Read all the lines we don't care about.
85
+ relevant_line = location_file.readline
86
+ relevant_line.match?(/#.*chef:silence_deprecation($|[^:]|:#{self.class.deprecation_key})/)
87
+ end
86
88
  end
87
89
 
88
90
  false
@@ -249,6 +251,14 @@ class Chef
249
251
  target 32
250
252
  end
251
253
 
254
+ class PolicyfileCompatMode < Base
255
+ target 35
256
+ end
257
+
258
+ class AttributeWhitelistConfiguration < Base
259
+ target 34
260
+ end
261
+
252
262
  class Generic < Base
253
263
  def url
254
264
  "https://docs.chef.io/chef_deprecations_client/"
@@ -174,6 +174,9 @@ class Chef
174
174
  class CannotDetermineWindowsInstallerType < Package; end
175
175
  class NoWindowsPackageSource < Package; end
176
176
 
177
+ # for example, if both recipes/default.yml, recipes/default.yaml are present
178
+ class AmbiguousYAMLFile < RuntimeError; end
179
+
177
180
  # Can not create staging file during file deployment
178
181
  class FileContentStagingError < RuntimeError
179
182
  def initialize(errors)
@@ -27,7 +27,7 @@ class Chef
27
27
  # Failed to register this client with the server.
28
28
  def self.registration_failed(node_name, exception, config)
29
29
  error_inspector = ErrorInspectors::RegistrationErrorInspector.new(node_name, exception, config)
30
- headline = "Chef encountered an error attempting to create the client \"#{node_name}\""
30
+ headline = "Chef Infra Client encountered an error attempting to create the client \"#{node_name}\""
31
31
  description = ErrorDescription.new(headline)
32
32
  error_inspector.add_explanation(description)
33
33
  description
@@ -35,7 +35,7 @@ class Chef
35
35
 
36
36
  def self.node_load_failed(node_name, exception, config)
37
37
  error_inspector = ErrorInspectors::NodeLoadErrorInspector.new(node_name, exception, config)
38
- headline = "Chef encountered an error attempting to load the node data for \"#{node_name}\""
38
+ headline = "Chef Infra Client encountered an error attempting to load the node data for \"#{node_name}\""
39
39
  description = ErrorDescription.new(headline)
40
40
  error_inspector.add_explanation(description)
41
41
  description
data/lib/chef/http.rb CHANGED
@@ -423,7 +423,7 @@ class Chef
423
423
  if response.is_a?(Net::HTTPServerError) && !Chef::Config.local_mode
424
424
  if http_retry_count - http_attempts >= 0
425
425
  sleep_time = 1 + (2**http_attempts) + rand(2**http_attempts)
426
- Chef::Log.error("Server returned error #{response.code} for #{url}, retrying #{http_attempts}/#{http_retry_count} in #{sleep_time}s")
426
+ Chef::Log.warn("Server returned error #{response.code} for #{url}, retrying #{http_attempts}/#{http_retry_count} in #{sleep_time}s") # Updated from error to warn
427
427
  sleep(sleep_time)
428
428
  redo
429
429
  end
@@ -432,7 +432,7 @@ class Chef
432
432
  end
433
433
  rescue SocketError, Errno::ETIMEDOUT, Errno::ECONNRESET => e
434
434
  if http_retry_count - http_attempts >= 0
435
- Chef::Log.error("Error connecting to #{url}, retry #{http_attempts}/#{http_retry_count}")
435
+ Chef::Log.warn("Error connecting to #{url}, retry #{http_attempts}/#{http_retry_count}") # Updated from error to warn
436
436
  sleep(http_retry_delay)
437
437
  retry
438
438
  end
@@ -440,21 +440,21 @@ class Chef
440
440
  raise e
441
441
  rescue Errno::ECONNREFUSED
442
442
  if http_retry_count - http_attempts >= 0
443
- Chef::Log.error("Connection refused connecting to #{url}, retry #{http_attempts}/#{http_retry_count}")
443
+ Chef::Log.warn("Connection refused connecting to #{url}, retry #{http_attempts}/#{http_retry_count}") # Updated from error to warn
444
444
  sleep(http_retry_delay)
445
445
  retry
446
446
  end
447
447
  raise Errno::ECONNREFUSED, "Connection refused connecting to #{url}, giving up"
448
448
  rescue Timeout::Error
449
449
  if http_retry_count - http_attempts >= 0
450
- Chef::Log.error("Timeout connecting to #{url}, retry #{http_attempts}/#{http_retry_count}")
450
+ Chef::Log.warn("Timeout connecting to #{url}, retry #{http_attempts}/#{http_retry_count}") # Updated from error to warn
451
451
  sleep(http_retry_delay)
452
452
  retry
453
453
  end
454
454
  raise Timeout::Error, "Timeout connecting to #{url}, giving up"
455
455
  rescue OpenSSL::SSL::SSLError => e
456
456
  if (http_retry_count - http_attempts >= 0) && !e.message.include?("certificate verify failed")
457
- Chef::Log.error("SSL Error connecting to #{url}, retry #{http_attempts}/#{http_retry_count}")
457
+ Chef::Log.warn("SSL Error connecting to #{url}, retry #{http_attempts}/#{http_retry_count}") # Updated from error to warn
458
458
  sleep(http_retry_delay)
459
459
  retry
460
460
  end
@@ -473,7 +473,7 @@ class Chef
473
473
  end
474
474
 
475
475
  # The server_name is the DNS or IP we are going to connect to, it is not necessarily
476
- # the node name, the fqdn, or the hostname of the server. This is a public API hook
476
+ # the node name, the fqdn, or the hostname of the server. This is a public API hook
477
477
  # which knife plugins use or inherit and override.
478
478
  #
479
479
  # @return [String] The DNS or IP that bootstrap will connect to
data/lib/chef/node.rb CHANGED
@@ -687,6 +687,25 @@ class Chef
687
687
  name <=> other.name
688
688
  end
689
689
 
690
+ # Returns hash of node data with attributes based on whitelist/blacklist rules.
691
+ def data_for_save
692
+ data = for_json
693
+ %w{automatic default normal override}.each do |level|
694
+ allowlist = allowlist_or_whitelist_config(level)
695
+ unless allowlist.nil? # nil => save everything
696
+ logger.info("Allowing #{level} node attributes for save.")
697
+ data[level] = Chef::AttributeAllowlist.filter(data[level], allowlist)
698
+ end
699
+
700
+ blocklist = blocklist_or_blacklist_config(level)
701
+ unless blocklist.nil? # nil => remove nothing
702
+ logger.info("Blocking #{level} node attributes for save")
703
+ data[level] = Chef::AttributeBlocklist.filter(data[level], blocklist)
704
+ end
705
+ end
706
+ data
707
+ end
708
+
690
709
  private
691
710
 
692
711
  def save_without_policyfile_attrs
@@ -712,7 +731,7 @@ class Chef
712
731
  # @param [String] level the attribute level
713
732
  def allowlist_or_whitelist_config(level)
714
733
  if Chef::Config["#{level}_attribute_whitelist".to_sym]
715
- Chef.deprecated(:attribute_blacklist_configuration, "Attribute whitelist configurations have been deprecated. Use the allowed_LEVEL_attribute configs instead")
734
+ Chef.deprecated(:attribute_whitelist_configuration, "Attribute whitelist configurations have been deprecated. Use the allowed_LEVEL_attribute configs instead")
716
735
  Chef::Config["#{level}_attribute_whitelist".to_sym]
717
736
  else
718
737
  Chef::Config["allowed_#{level}_attributes".to_sym]
@@ -732,24 +751,6 @@ class Chef
732
751
  end
733
752
  end
734
753
 
735
- def data_for_save
736
- data = for_json
737
- %w{automatic default normal override}.each do |level|
738
- allowlist = allowlist_or_whitelist_config(level)
739
- unless allowlist.nil? # nil => save everything
740
- logger.info("Allowing #{level} node attributes for save.")
741
- data[level] = Chef::AttributeAllowlist.filter(data[level], allowlist)
742
- end
743
-
744
- blocklist = blocklist_or_blacklist_config(level)
745
- unless blocklist.nil? # nil => remove nothing
746
- logger.info("Blocking #{level} node attributes for save")
747
- data[level] = Chef::AttributeBlocklist.filter(data[level], blocklist)
748
- end
749
- end
750
- data
751
- end
752
-
753
754
  # Returns a UUID that uniquely identifies this node for reporting reasons.
754
755
  #
755
756
  # The node is read in from disk if it exists, or it's generated if it does
@@ -148,6 +148,11 @@ class Chef
148
148
  # consume_external_attrs may add items to the run_list. Save the
149
149
  # expanded run_list, which we will pass to the server later to
150
150
  # determine which versions of cookbooks to use.
151
+
152
+ unless Chef::Config[:policy_document_native_api]
153
+ Chef.deprecated(:policyfile_compat_mode, "The chef-server 11 policyfile compat mode is deprecated, please set policy_document_native_api to true in your config")
154
+ end
155
+
151
156
  node.reset_defaults_and_overrides
152
157
 
153
158
  node.consume_external_attrs(ohai_data, json_attribs)
@@ -158,7 +158,7 @@ class Chef
158
158
  if new_resource.group_name && (current_resource.group_name != new_resource.group_name)
159
159
  dscl_create_group
160
160
  end
161
- if new_resource.gid && (current_resource.gid != new_resource.gid)
161
+ if new_resource.gid && (current_resource.gid != new_resource.gid.to_s)
162
162
  set_gid
163
163
  end
164
164
  if new_resource.members || new_resource.excluded_members
@@ -124,6 +124,11 @@ class Chef
124
124
  command.push("-RequiredVersion #{version}") if version
125
125
  command.push("-Source #{new_resource.source}") if new_resource.source && cmdlet_name =~ Regexp.union(/Install-Package/, /Find-Package/)
126
126
  command.push("-SkipPublisherCheck") if new_resource.skip_publisher_check && cmdlet_name !~ /Find-Package/
127
+ if new_resource.options && cmdlet_name !~ Regexp.union(/Get-Package/, /Find-Package/)
128
+ new_resource.options.each do |arg|
129
+ command.push(arg) unless command.include?(arg)
130
+ end
131
+ end
127
132
  command.push(").Version")
128
133
  command.join(" ")
129
134
  end
@@ -65,7 +65,7 @@ class Chef
65
65
  context[:template_finder] = template_finder
66
66
 
67
67
  # helper variables
68
- context[:cookbook_name] = new_resource.cookbook_name unless context.keys.include?(:coookbook_name)
68
+ context[:cookbook_name] = new_resource.cookbook_name unless context.keys.include?(:cookbook_name)
69
69
  context[:recipe_name] = new_resource.recipe_name unless context.keys.include?(:recipe_name)
70
70
  context[:recipe_line_string] = new_resource.source_line unless context.keys.include?(:recipe_line_string)
71
71
  context[:recipe_path] = new_resource.source_line_file unless context.keys.include?(:recipe_path)
@@ -75,6 +75,7 @@ class Chef
75
75
  file cert_path do
76
76
  content new_resource.certificate
77
77
  mode "0640"
78
+ sensitive new_resource.sensitive
78
79
  end
79
80
  end
80
81
 
@@ -34,7 +34,7 @@ class Chef
34
34
 
35
35
  property :cask_name, String,
36
36
  description: "An optional property to set the cask name if it differs from the resource block's name.",
37
- regex: %r{^[\w/-]+$},
37
+ regex: %r{^[\w/\-@]+$},
38
38
  validation_message: "The provided Homebrew cask name is not valid. Cask names can contain alphanumeric characters, _, -, or / only!",
39
39
  name_property: true
40
40
 
@@ -54,9 +54,12 @@ class Chef
54
54
  default: lazy { find_homebrew_username }
55
55
 
56
56
  action :install do
57
- description "Install an application packaged as a Homebrew cask."
58
-
59
- homebrew_tap "homebrew/cask" if new_resource.install_cask
57
+ if new_resource.install_cask
58
+ homebrew_tap "homebrew/cask" do
59
+ homebrew_path new_resource.homebrew_path
60
+ owner new_resource.owner
61
+ end
62
+ end
60
63
 
61
64
  unless casked?
62
65
  converge_by("install cask #{new_resource.cask_name} #{new_resource.options}") do
@@ -69,9 +72,12 @@ class Chef
69
72
  end
70
73
 
71
74
  action :remove do
72
- description "Remove an application packaged as a Homebrew cask."
73
-
74
- homebrew_tap "homebrew/cask" if new_resource.install_cask
75
+ if new_resource.install_cask
76
+ homebrew_tap "homebrew/cask" do
77
+ homebrew_path new_resource.homebrew_path
78
+ owner new_resource.owner
79
+ end
80
+ end
75
81
 
76
82
  if casked?
77
83
  converge_by("uninstall cask #{new_resource.cask_name}") do
@@ -41,7 +41,7 @@ class Chef
41
41
  sensitive: true
42
42
 
43
43
  property :mount_point, String, name_property: true,
44
- coerce: proc { |arg| arg.chomp("/") }, # Removed "/" from the end of str, because it was causing idempotency issue.
44
+ coerce: proc { |arg| (arg == "/" || arg.match?(":/$")) ? arg : arg.chomp("/") }, # Removed "/" from the end of str, because it was causing idempotency issue.
45
45
  description: "The directory (or path) in which the device is to be mounted. Defaults to the name of the resource block if not provided."
46
46
 
47
47
  property :device, String, identity: true,
@@ -34,11 +34,11 @@ class Chef
34
34
  action :attach do
35
35
  description "Attach the node to a subscription pool."
36
36
 
37
- execute "Attach subscription pool #{new_resource.pool_id}" do
38
- command "subscription-manager attach --pool=#{new_resource.pool_id}"
39
- default_env true
40
- action :run
41
- not_if { subscription_attached?(new_resource.pool_id) }
37
+ unless subscription_attached?(new_resource.pool_id)
38
+ converge_by("attach subscription pool #{new_resource.pool_id}") do
39
+ shell_out!("subscription-manager attach --pool=#{new_resource.pool_id}")
40
+ build_resource(:package, "rhsm_subscription-#{new_resource.pool_id}-flush_cache").run_action(:flush_cache)
41
+ end
42
42
  end
43
43
  end
44
44
 
@@ -22,6 +22,12 @@
22
22
  <% next if instance_variable_get(prop).nil? || instance_variable_get(prop).empty? -%>
23
23
  <%=prop.delete_prefix("@") %> <%= instance_variable_get(prop).inspect %>
24
24
  <% end -%>
25
+ <%# ohai_disabled_plugins and ohai_optional_plugins properties don't match the config value perfectly-%>
26
+ <% %w(@ohai_disabled_plugins
27
+ @ohai_optional_plugins).each do |prop| -%>
28
+ <% next if instance_variable_get(prop).nil? || instance_variable_get(prop).empty? -%>
29
+ <%=prop.gsub("@ohai_", "ohai.") %> <%= instance_variable_get(prop).inspect %>
30
+ <% end -%>
25
31
  <%# log_location is special due to STDOUT/STDERR from String -> IO Object -%>
26
32
  <% unless @log_location.nil? %>
27
33
  <% if @log_location.is_a?(String) && %w(STDOUT STDERR).include?(@log_location) -%>
@@ -113,7 +113,7 @@ class Chef
113
113
  when Hash
114
114
  IniParse.gen do |doc|
115
115
  content.each_pair do |sect, opts|
116
- doc.section(sect) do |section|
116
+ doc.section(sect, { option_sep: "=" }) do |section|
117
117
  opts.each_pair do |opt, val|
118
118
  [val].flatten.each do |v|
119
119
  section.option(opt, v)
@@ -83,6 +83,7 @@ class Chef
83
83
  source ::File.expand_path("support/ulimit.erb", __dir__)
84
84
  local true
85
85
  mode "0644"
86
+ sensitive new_resource.sensitive
86
87
  variables(
87
88
  ulimit_user: new_resource.username,
88
89
  filehandle_limit: new_resource.filehandle_limit,
@@ -17,6 +17,7 @@
17
17
  # limitations under the License.
18
18
 
19
19
  require_relative "../resource"
20
+ require "tempfile" unless defined?(Tempfile)
20
21
 
21
22
  class Chef
22
23
  class Resource
@@ -27,6 +28,7 @@ class Chef
27
28
 
28
29
  # The valid policy_names options found here
29
30
  # https://github.com/ChrisAWalker/cSecurityOptions under 'AccountSettings'
31
+ # This needs to be revisited - the list at the link above is non-exhaustive and is missing a couple of items
30
32
  policy_names = %w{LockoutDuration
31
33
  MaximumPasswordAge
32
34
  MinimumPasswordAge
@@ -35,6 +37,8 @@ class Chef
35
37
  PasswordHistorySize
36
38
  LockoutBadCount
37
39
  ResetLockoutCount
40
+ AuditPolicyChange
41
+ LockoutDuration
38
42
  RequireLogonToChangePassword
39
43
  ForceLogoffWhenHourExpire
40
44
  NewAdministratorName
@@ -43,7 +47,7 @@ class Chef
43
47
  LSAAnonymousNameLookup
44
48
  EnableAdminAccount
45
49
  EnableGuestAccount
46
- }
50
+ }
47
51
  description "Use the **windows_security_policy** resource to set a security policy on the Microsoft Windows platform."
48
52
  introduced "16.0"
49
53
 
@@ -83,6 +87,55 @@ class Chef
83
87
  description: "Policy value to be set for policy name."
84
88
 
85
89
  load_current_value do |desired|
90
+ current_state = load_security_options
91
+
92
+ if desired.secoption == "ResetLockoutCount"
93
+ if desired.secvalue.to_i > 30
94
+ raise Chef::Exceptions::ValidationFailed, "The \"ResetLockoutCount\" value cannot be greater than 30 minutes"
95
+ end
96
+ end
97
+ if (desired.secoption == "ResetLockoutCount" || desired.secoption == "LockoutDuration") && current_state["LockoutBadCount"] == "0"
98
+ raise Chef::Exceptions::ValidationFailed, "#{desired.secoption} cannot be set unless the \"LockoutBadCount\" security policy has been set to a non-zero value"
99
+ end
100
+
101
+ secvalue current_state[desired.secoption.to_s]
102
+ end
103
+
104
+ action :set do
105
+ converge_if_changed :secvalue do
106
+ security_option = new_resource.secoption
107
+ security_value = new_resource.secvalue
108
+
109
+ file = Tempfile.new(["#{security_option}", ".inf"])
110
+ case security_option
111
+ when "LockoutBadCount"
112
+ cmd = "net accounts /LockoutThreshold:#{security_value}"
113
+ when "ResetLockoutCount"
114
+ cmd = "net accounts /LockoutWindow:#{security_value}"
115
+ when "LockoutDuration"
116
+ cmd = "net accounts /LockoutDuration:#{security_value}"
117
+ when "NewAdministratorName", "NewGuestName"
118
+ policy_line = "#{security_option} = \"#{security_value}\""
119
+ file.write("[Unicode]\r\nUnicode=yes\r\n[System Access]\r\n#{policy_line}\r\n[Version]\r\nsignature=\"$CHICAGO$\"\r\nRevision=1\r\n")
120
+ file.close
121
+ file_path = file.path.gsub("/", '\\')
122
+ cmd = "C:\\Windows\\System32\\secedit /configure /db C:\\windows\\security\\new.sdb /cfg #{file_path} /areas SECURITYPOLICY"
123
+ else
124
+ policy_line = "#{security_option} = #{security_value}"
125
+ file.write("[Unicode]\r\nUnicode=yes\r\n[System Access]\r\n#{policy_line}\r\n[Version]\r\nsignature=\"$CHICAGO$\"\r\nRevision=1\r\n")
126
+ file.close
127
+ file_path = file.path.gsub("/", '\\')
128
+ cmd = "C:\\Windows\\System32\\secedit /configure /db C:\\windows\\security\\new.sdb /cfg #{file_path} /areas SECURITYPOLICY"
129
+ end
130
+ shell_out!(cmd)
131
+ file.unlink
132
+ end
133
+ end
134
+
135
+ private
136
+
137
+ # Loads powershell to get current state on security options
138
+ def load_security_options
86
139
  powershell_code = <<-CODE
87
140
  C:\\Windows\\System32\\secedit /export /cfg $env:TEMP\\secopts_export.inf | Out-Null
88
141
  # cspell:disable-next-line
@@ -108,44 +161,7 @@ class Chef
108
161
  LockoutBadCount = $security_options_hash.LockoutBadCount
109
162
  })
110
163
  CODE
111
- output = powershell_exec(powershell_code)
112
- current_value_does_not_exist! if output.result.empty?
113
- state = output.result
114
-
115
- if desired.secoption == "ResetLockoutCount" || desired.secoption == "LockoutDuration"
116
- if state["LockoutBadCount"] == "0"
117
- raise Chef::Exceptions::ValidationFailed.new "#{desired.secoption} cannot be set unless the \"LockoutBadCount\" security policy has been set to a non-zero value"
118
- else
119
- secvalue state[desired.secoption.to_s]
120
- end
121
- else
122
- secvalue state[desired.secoption.to_s]
123
- end
124
- end
125
-
126
- action :set do
127
- converge_if_changed :secvalue do
128
- security_option = new_resource.secoption
129
- security_value = new_resource.secvalue
130
-
131
- cmd = <<-EOH
132
- $security_option = "#{security_option}"
133
- C:\\Windows\\System32\\secedit /export /cfg $env:TEMP\\#{security_option}_Export.inf
134
- if ( ($security_option -match "NewGuestName") -Or ($security_option -match "NewAdministratorName") )
135
- {
136
- $#{security_option}_Remediation = (Get-Content $env:TEMP\\#{security_option}_Export.inf) | Foreach-Object { $_ -replace '#{security_option}\\s*=\\s*\\"\\w*\\"', '#{security_option} = "#{security_value}"' } | Set-Content $env:TEMP\\#{security_option}_Export.inf
137
- C:\\Windows\\System32\\secedit /configure /db $env:windir\\security\\new.sdb /cfg $env:TEMP\\#{security_option}_Export.inf /areas SECURITYPOLICY
138
- }
139
- else
140
- {
141
- $#{security_option}_Remediation = (Get-Content $env:TEMP\\#{security_option}_Export.inf) | Foreach-Object { $_ -replace "#{security_option}\\s*=\\s*\\d*", "#{security_option} = #{security_value}" } | Set-Content $env:TEMP\\#{security_option}_Export.inf
142
- C:\\Windows\\System32\\secedit /configure /db $env:windir\\security\\new.sdb /cfg $env:TEMP\\#{security_option}_Export.inf /areas SECURITYPOLICY
143
- }
144
- Remove-Item $env:TEMP\\#{security_option}_Export.inf -force
145
- EOH
146
-
147
- powershell_exec!(cmd)
148
- end
164
+ powershell_exec(powershell_code).result
149
165
  end
150
166
  end
151
167
  end
@@ -106,7 +106,9 @@ class Chef
106
106
  #
107
107
  # @return [Integer]
108
108
  def consent_behavior_users_symbol_to_reg(sym)
109
- %i{auto_deny secure_prompt_for_creds prompt_for_creds}.index(sym)
109
+ # Since 2 isn't a valid value for ConsentPromptBehaviorUser, assign the value at index as nil.
110
+ # https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#registry-key-settings
111
+ [:auto_deny, :secure_prompt_for_creds, nil, :prompt_for_creds].index(sym)
110
112
  end
111
113
  end
112
114
  end
@@ -139,7 +139,7 @@ class Chef
139
139
  coerce: proc { |v| Array(v) },
140
140
  callbacks: {
141
141
  "Privilege property restricted to the following values: #{PRIVILEGE_OPTS}" => lambda { |n| (n - PRIVILEGE_OPTS).empty? },
142
- }
142
+ }, identity: true
143
143
 
144
144
  load_current_value do |new_resource|
145
145
  if new_resource.principal && (new_resource.action.include?(:add) || new_resource.action.include?(:remove))
data/lib/chef/resource.rb CHANGED
@@ -1513,7 +1513,7 @@ class Chef
1513
1513
  # @return Chef::CookbookVersion The cookbook in which this Resource was defined.
1514
1514
  #
1515
1515
  def cookbook_version
1516
- if cookbook_name
1516
+ if cookbook_name && cookbook_name != "@recipe_files"
1517
1517
  run_context.cookbook_collection[cookbook_name]
1518
1518
  end
1519
1519
  end
@@ -41,7 +41,7 @@ class Chef
41
41
  as_hash["result"] = action_record.action.to_s
42
42
  if new_resource.cookbook_name
43
43
  as_hash["cookbook_name"] = new_resource.cookbook_name
44
- as_hash["cookbook_version"] = new_resource.cookbook_version.version
44
+ as_hash["cookbook_version"] = new_resource.cookbook_version&.version
45
45
  end
46
46
 
47
47
  as_hash
@@ -198,9 +198,9 @@ module Shell
198
198
  prints a detailed explanation of the command if available, or the
199
199
  description if no explanation is available.
200
200
  E
201
- def help(commmand = nil)
202
- if commmand
203
- explain_command(commmand)
201
+ def help(command = nil)
202
+ if command
203
+ explain_command(command)
204
204
  else
205
205
  puts help_banner
206
206
  end
data/lib/chef/version.rb CHANGED
@@ -23,7 +23,7 @@ require_relative "version_string"
23
23
 
24
24
  class Chef
25
25
  CHEF_ROOT = File.expand_path("..", __dir__)
26
- VERSION = Chef::VersionString.new("16.14.1")
26
+ VERSION = Chef::VersionString.new("16.17.4")
27
27
  end
28
28
 
29
29
  #