chef 17.9.52 → 17.10.95

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/Rakefile +2 -2
  4. data/chef-universal-mingw32.gemspec +3 -2
  5. data/chef.gemspec +6 -6
  6. data/lib/chef/api_client.rb +1 -1
  7. data/lib/chef/client.rb +17 -2
  8. data/lib/chef/compliance/input_collection.rb +1 -1
  9. data/lib/chef/compliance/profile_collection.rb +1 -1
  10. data/lib/chef/compliance/waiver_collection.rb +1 -1
  11. data/lib/chef/dsl/secret.rb +113 -5
  12. data/lib/chef/mixin/checksum.rb +6 -0
  13. data/lib/chef/mixin/properties.rb +6 -0
  14. data/lib/chef/node/attribute.rb +20 -3
  15. data/lib/chef/node/mixin/deep_merge_cache.rb +4 -4
  16. data/lib/chef/policy_builder/expand_node_object.rb +1 -2
  17. data/lib/chef/policy_builder/policyfile.rb +1 -1
  18. data/lib/chef/provider/file.rb +2 -2
  19. data/lib/chef/provider/package/chocolatey.rb +18 -1
  20. data/lib/chef/provider/package/powershell.rb +1 -1
  21. data/lib/chef/provider/package/rubygems.rb +6 -6
  22. data/lib/chef/provider/package/windows.rb +1 -1
  23. data/lib/chef/provider/package/yum/python_helper.rb +14 -1
  24. data/lib/chef/provider/service/windows.rb +4 -4
  25. data/lib/chef/provider/user/windows.rb +2 -2
  26. data/lib/chef/provider/user.rb +5 -1
  27. data/lib/chef/resource/chef_client_config.rb +5 -0
  28. data/lib/chef/resource/locale.rb +5 -2
  29. data/lib/chef/resource/macos_userdefaults.rb +9 -5
  30. data/lib/chef/resource/rhsm_register.rb +19 -0
  31. data/lib/chef/resource/support/client.erb +1 -2
  32. data/lib/chef/resource/windows_certificate.rb +54 -43
  33. data/lib/chef/resource/windows_pagefile.rb +28 -21
  34. data/lib/chef/resource/windows_user_privilege.rb +36 -26
  35. data/lib/chef/resource.rb +2 -1
  36. data/lib/chef/run_context.rb +16 -0
  37. data/lib/chef/secret_fetcher/hashi_vault.rb +1 -1
  38. data/lib/chef/version.rb +1 -1
  39. data/lib/chef/win32/version.rb +2 -1
  40. data/spec/data/trusted_certs/example.crt +29 -20
  41. data/spec/data/trusted_certs/example_no_cn.crt +30 -34
  42. data/spec/data/trusted_certs/opscode.pem +33 -54
  43. data/spec/functional/resource/chocolatey_package_spec.rb +32 -20
  44. data/spec/functional/resource/dnf_package_spec.rb +15 -0
  45. data/spec/functional/resource/macos_userdefaults_spec.rb +4 -4
  46. data/spec/functional/resource/windows_certificate_spec.rb +41 -13
  47. data/spec/functional/resource/windows_font_spec.rb +1 -1
  48. data/spec/functional/resource/windows_pagefile_spec.rb +31 -4
  49. data/spec/functional/resource/yum_package_spec.rb +16 -1
  50. data/spec/functional/shell_spec.rb +6 -0
  51. data/spec/unit/client_spec.rb +6 -3
  52. data/spec/unit/compliance/reporter/chef_server_automate_spec.rb +1 -1
  53. data/spec/unit/daemon_spec.rb +1 -5
  54. data/spec/unit/dsl/secret_spec.rb +127 -23
  55. data/spec/unit/mixin/checksum_spec.rb +28 -0
  56. data/spec/unit/provider/package/chocolatey_spec.rb +19 -3
  57. data/spec/unit/provider/package/rubygems_spec.rb +1 -1
  58. data/spec/unit/provider/user/linux_spec.rb +55 -0
  59. data/spec/unit/resource/chef_client_config_spec.rb +8 -0
  60. data/spec/unit/resource/macos_user_defaults_spec.rb +4 -4
  61. data/spec/unit/resource_spec.rb +22 -1
  62. data/spec/unit/run_context_spec.rb +16 -0
  63. metadata +36 -36
  64. /data/spec/functional/assets/chocolatey_feed/{test-A.1.0.nupkg → test-A.1.0.0.nupkg} +0 -0
  65. /data/spec/functional/assets/chocolatey_feed/{test-A.1.5.nupkg → test-A.1.5.0.nupkg} +0 -0
  66. /data/spec/functional/assets/chocolatey_feed/{test-A.2.0.nupkg → test-A.2.0.0.nupkg} +0 -0
  67. /data/spec/functional/assets/chocolatey_feed/{test-B.1.0.nupkg → test-B.1.0.0.nupkg} +0 -0
  68. /data/spec/functional/assets/yumrepo/repodata/{4632d67cb92636e7575d911c24f0e04d3505a944e97c483abe0c3e73a7c62d33-filelists.sqlite.bz2 → 01a3b-filelists.sqlite.bz2} +0 -0
  69. /data/spec/functional/assets/yumrepo/repodata/{bdb4f5f1492a3b9532f22c43110a81500dd744f23da0aec5c33b2a41317c737d-filelists.xml.gz → 401dc-filelists.xml.gz} +0 -0
  70. /data/spec/functional/assets/yumrepo/repodata/{a845d418f919d2115ab95a56b2c76f6825ad0d0bede49181a55c04f58995d057-primary.sqlite.bz2 → 5dc1e-primary.sqlite.bz2} +0 -0
  71. /data/spec/functional/assets/yumrepo/repodata/{74599b793e54d877323837d2d81a1c3c594c44e4335f9528234bb490f7b9b439-other.xml.gz → 6bf96-other.xml.gz} +0 -0
  72. /data/spec/functional/assets/yumrepo/repodata/{af9b7cf9ef23bd7b43068d74a460f3b5d06753d638e58e4a0c9edc35bfb9cdc4-other.sqlite.bz2 → 7c365-other.sqlite.bz2} +0 -0
  73. /data/spec/functional/assets/yumrepo/repodata/{c10d1d34ce99e02f12ec96ef68360543ab1bb7c3cb81a4a2bf78df7d8597e9df-primary.xml.gz → dabe2-primary.xml.gz} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 944116661453cac4b29602c659f1f9ce7bb6e7c5b6742ab4d8982fdb7ccf9543
4
- data.tar.gz: bbc55e863772d4e5d72d5936b2a034c43746502dea51734b9e1402b0055070e5
3
+ metadata.gz: cbd02b60802f0874cef53b37a8b8d5996600fdcb6c53c29263fe454b18bf0cb6
4
+ data.tar.gz: 70e96d302b07784e0b2fe4c93141f72510169f5a5456f6084d6d3f51fece3a33
5
5
  SHA512:
6
- metadata.gz: bdb9b7dc0f162c740995850f6a32a32c618448cc5d475dba7d30acec38eaa2e98a259b3051f82d7ed63ba5000a9ac259b6c0643d1a7cc05b69bdb7d212d266f5
7
- data.tar.gz: 17418b25e596b3bf1d9942357b99c23cf0e9ffdf3a74a57e1943d48c26f8efd410ca50fc1e64740c721e8a97761bcd3fe504a434ad80a2cb40f4adf3419b3b25
6
+ metadata.gz: f61a95453d1b50956c6c0b72552b3c8581b1707606589375352a0bdbbde54f7504c9a37d635b4ac2b2299ed33e75dfdec535ca2802b5be1e60a4ad1d33bf35b0
7
+ data.tar.gz: 0c8fbbd7634626b2178516af1df72274d352f789097b5fde508b38d00e98860c6c359f391a4c2bc2573ff257b63a7d5833937ef3e0c9b1a1ea1e709504093c41
data/Gemfile CHANGED
@@ -15,12 +15,12 @@ else
15
15
  gem "chef-bin" # rubocop:disable Bundler/DuplicatedGem
16
16
  end
17
17
 
18
- gem "cheffish", "~> 17.0"
18
+ gem "cheffish", "~> 17.0.0"
19
19
 
20
20
  group(:omnibus_package) do
21
21
  gem "appbundler"
22
22
  gem "rb-readline"
23
- gem "inspec-core-bin", "~> 4.24" # need to provide the binaries for inspec
23
+ gem "inspec-core-bin", ">= 4.24" # need to provide the binaries for inspec
24
24
  gem "chef-vault"
25
25
  end
26
26
 
data/Rakefile CHANGED
@@ -70,7 +70,7 @@ Bundler::GemHelper.install_tasks name: gemspec
70
70
  task :install do
71
71
  chef_bin_path = ::File.join(::File.dirname(__FILE__), "chef-bin")
72
72
  Dir.chdir(chef_bin_path) do
73
- sh("rake install:force")
73
+ system "rake install:force"
74
74
  end
75
75
  end
76
76
 
@@ -80,7 +80,7 @@ namespace :install do
80
80
  task :local do
81
81
  chef_bin_path = ::File.join(::File.dirname(__FILE__), "chef-bin")
82
82
  Dir.chdir(chef_bin_path) do
83
- sh("rake install:local")
83
+ system "rake install:local"
84
84
  end
85
85
  end
86
86
  end
@@ -11,10 +11,11 @@ gemspec.add_dependency "win32-mmap", "~> 0.4.1"
11
11
  gemspec.add_dependency "win32-mutex", "~> 0.4.2"
12
12
  gemspec.add_dependency "win32-process", "~> 0.9"
13
13
  gemspec.add_dependency "win32-service", ">= 2.1.5", "< 3.0"
14
- gemspec.add_dependency "wmi-lite", "~> 1.0"
15
14
  gemspec.add_dependency "win32-taskscheduler", "~> 2.0"
15
+ gemspec.add_dependency "win32-certstore", "~> 0.6.15"
16
+ gemspec.add_dependency "wmi-lite", "~> 1.0"
16
17
  gemspec.add_dependency "iso8601", ">= 0.12.1", "< 0.14" # validate 0.14 when it comes out
17
- gemspec.add_dependency "win32-certstore", "~> 0.6.2" # 0.5+ required for specifying user vs. system store
18
+ gemspec.add_dependency "chef-powershell", "~> 1.0.12" # 0.5+ required for specifying user vs. system store
18
19
  gemspec.extensions << "ext/win32-eventlog/Rakefile"
19
20
  gemspec.files += Dir.glob("{distro,ext}/**/*")
20
21
 
data/chef.gemspec CHANGED
@@ -22,11 +22,11 @@ Gem::Specification.new do |s|
22
22
  s.email = "adam@chef.io"
23
23
  s.homepage = "https://www.chef.io"
24
24
 
25
- s.required_ruby_version = ">= 2.6.0"
25
+ s.required_ruby_version = ">= 2.7.0"
26
26
 
27
27
  s.add_dependency "chef-config", "= #{Chef::VERSION}"
28
28
  s.add_dependency "chef-utils", "= #{Chef::VERSION}"
29
- s.add_dependency "train-core", "~> 3.2", ">= 3.2.28" # 3.2.28 fixes sudo prompts. See https://github.com/chef/chef/pull/9635
29
+ s.add_dependency "train-core", "~> 3.10" # 3.2.28 fixes sudo prompts. See https://github.com/chef/chef/pull/9635
30
30
  s.add_dependency "train-winrm", ">= 0.2.5"
31
31
 
32
32
  s.add_dependency "license-acceptance", ">= 1.0.5", "< 3"
@@ -36,13 +36,13 @@ Gem::Specification.new do |s|
36
36
  s.add_dependency "mixlib-shellout", ">= 3.1.1", "< 4.0"
37
37
  s.add_dependency "mixlib-archive", ">= 0.4", "< 2.0"
38
38
  s.add_dependency "ohai", "~> 17.0"
39
- s.add_dependency "inspec-core", "~> 4.23"
39
+ s.add_dependency "inspec-core", ">= 4.23"
40
40
 
41
- s.add_dependency "ffi", ">= 1.5.0"
41
+ s.add_dependency "ffi", "~> 1.15.0"
42
42
  s.add_dependency "ffi-yajl", "~> 2.2"
43
- s.add_dependency "net-sftp", ">= 2.1.2", "< 4.0" # remote_file resource
43
+ s.add_dependency "net-sftp", ">= 2.1.2", "< 5.0" # remote_file resource
44
44
  s.add_dependency "erubis", "~> 2.7" # template resource / cookbook syntax check
45
- s.add_dependency "diff-lcs", ">= 1.2.4", "< 1.4.0" # 1.4 breaks output. Used in lib/chef/util/diff
45
+ s.add_dependency "diff-lcs", ">= 1.2.4", "!= 1.4.0", "< 1.6.0" # 1.4 breaks output. Used in lib/chef/util/diff
46
46
  s.add_dependency "ffi-libarchive", "~> 1.0", ">= 1.0.3" # archive_file resource
47
47
  s.add_dependency "chef-zero", ">= 14.0.11"
48
48
  s.add_dependency "chef-vault" # chef-vault resources and helpers
@@ -196,7 +196,7 @@ class Chef
196
196
  end
197
197
 
198
198
  def reregister
199
- reregistered_self = http_api.put("clients/#{name}", { name: name, admin: admin, validator: validator, private_key: true })
199
+ reregistered_self = http_api.put("clients/#{name}", name: name, admin: admin, validator: validator, private_key: true )
200
200
  if reregistered_self.respond_to?(:[])
201
201
  private_key(reregistered_self["private_key"])
202
202
  else
data/lib/chef/client.rb CHANGED
@@ -326,12 +326,27 @@ class Chef
326
326
  def warn_if_eol
327
327
  require_relative "version"
328
328
 
329
+ # New Date format is YYYY-MM-DD or false
330
+ new_date = eol_override
331
+
329
332
  # We make a release every year so take the version you're on + 2006 and you get
330
333
  # the year it goes EOL
331
334
  eol_year = 2006 + Gem::Version.new(Chef::VERSION).segments.first
335
+ cut_off_date = !!new_date ? Time.parse(new_date) : Time.new(eol_year, 5, 01)
336
+
337
+ return if Time.now < cut_off_date
332
338
 
333
- if Time.now > Time.new(eol_year, 5, 01)
334
- logger.warn("This release of #{ChefUtils::Dist::Infra::PRODUCT} became end of life (EOL) on May 1st #{eol_year}. Please update to a supported release to receive new features, bug fixes, and security updates.")
339
+ logger.warn("This release of #{ChefUtils::Dist::Infra::PRODUCT} became end of life (EOL) on #{cut_off_date.strftime("%b %d, %Y")}. Please update to a supported release to receive new features, bug fixes, and security updates.")
340
+ end
341
+
342
+ def eol_override
343
+ # If you want to override the existing EOL date, add a file in the root of Chef
344
+ # put a date in it in the form of YYYY-DD-MM.
345
+ override_file = "EOL_override"
346
+ if File.exist?(override_file)
347
+ File.read(File.expand_path(override_file)).strip
348
+ else
349
+ false
335
350
  end
336
351
  end
337
352
 
@@ -40,7 +40,7 @@ class Chef
40
40
  def from_file(filename, cookbook_name)
41
41
  new_input = Input.from_file(events, filename, cookbook_name)
42
42
  self << new_input
43
- events.compliance_input_loaded(new_input)
43
+ events&.compliance_input_loaded(new_input)
44
44
  end
45
45
 
46
46
  # Add a input from a raw hash. This input will be enabled by default.
@@ -41,7 +41,7 @@ class Chef
41
41
  def from_file(path, cookbook_name)
42
42
  new_profile = Profile.from_file(events, path, cookbook_name)
43
43
  self << new_profile
44
- events.compliance_profile_loaded(new_profile)
44
+ events&.compliance_profile_loaded(new_profile)
45
45
  end
46
46
 
47
47
  # @return [Boolean] if any of the profiles are enabled
@@ -40,7 +40,7 @@ class Chef
40
40
  def from_file(filename, cookbook_name)
41
41
  new_waiver = Waiver.from_file(events, filename, cookbook_name)
42
42
  self << new_waiver
43
- events.compliance_waiver_loaded(new_waiver)
43
+ events&.compliance_waiver_loaded(new_waiver)
44
44
  end
45
45
 
46
46
  # Add a waiver from a raw hash. This waiver will be enabled by default.
@@ -21,6 +21,118 @@ class Chef
21
21
  module DSL
22
22
  module Secret
23
23
 
24
+ #
25
+ # This allows you to set the default secret service that is used when
26
+ # fetching secrets.
27
+ #
28
+ # @example
29
+ #
30
+ # default_secret_service :hashi_vault
31
+ # val1 = secret(name: "test1", config: { region: "us-west-1" })
32
+ #
33
+ # @example
34
+ #
35
+ # default_secret_service #=> nil
36
+ # default_secret_service :hashi_vault
37
+ # default_secret_service #=> :hashi_vault
38
+ #
39
+ # @param [Symbol] service default secret service to use when fetching secrets
40
+ # @return [Symbol, nil] default secret service to use when fetching secrets
41
+ #
42
+ def default_secret_service(service = nil)
43
+ return run_context.default_secret_service if service.nil?
44
+ raise Chef::Exceptions::Secret::InvalidFetcherService.new("Unsupported secret service: #{service.inspect}", Chef::SecretFetcher::SECRET_FETCHERS) unless Chef::SecretFetcher::SECRET_FETCHERS.include?(service)
45
+
46
+ run_context.default_secret_service = service
47
+ end
48
+
49
+ #
50
+ # This allows you to set the secret service for the scope of the block
51
+ # passed into this method.
52
+ #
53
+ # @example
54
+ #
55
+ # with_secret_service :hashi_vault do
56
+ # val1 = secret(name: "test1", config: { region: "us-west-1" })
57
+ # val2 = secret(name: "test2", config: { region: "us-west-1" })
58
+ # end
59
+ #
60
+ # @example Combine with #with_secret_config
61
+ #
62
+ # with_secret_service :hashi_vault do
63
+ # with_secret_config region: "us-west-1" do
64
+ # val1 = secret(name: "test1")
65
+ # val2 = secret(name: "test2")
66
+ # end
67
+ # end
68
+ #
69
+ # @param [Symbol] service The default secret service to use when fetching secrets
70
+ #
71
+ def with_secret_service(service)
72
+ raise ArgumentError, "You must pass a block to #with_secret_service" unless block_given?
73
+
74
+ begin
75
+ old_service = default_secret_service
76
+ # Use "public" API for input validation
77
+ default_secret_service(service)
78
+ yield
79
+ ensure
80
+ # Use "private" API so we can set back to nil
81
+ run_context.default_secret_service = old_service
82
+ end
83
+ end
84
+
85
+ #
86
+ # This allows you to set the default secret config that is used when
87
+ # fetching secrets.
88
+ #
89
+ # @example
90
+ #
91
+ # default_secret_config region: "us-west-1"
92
+ # val1 = secret(name: "test1", service: :hashi_vault)
93
+ #
94
+ # @example
95
+ #
96
+ # default_secret_config #=> {}
97
+ # default_secret_service region: "us-west-1"
98
+ # default_secret_service #=> { region: "us-west-1" }
99
+ #
100
+ # @param [Hash<Symbol,Object>] config The default configuration options to apply when fetching secrets
101
+ # @return [Hash<Symbol,Object>]
102
+ #
103
+ def default_secret_config(**config)
104
+ return run_context.default_secret_config if config.empty?
105
+
106
+ run_context.default_secret_config = config
107
+ end
108
+
109
+ #
110
+ # This allows you to set the secret config for the scope of the block
111
+ # passed into this method.
112
+ #
113
+ # @example
114
+ #
115
+ # with_secret_config region: "us-west-1" do
116
+ # val1 = secret(name: "test1", service: :hashi_vault)
117
+ # val2 = secret(name: "test2", service: :hashi_vault)
118
+ # end
119
+ #
120
+ # @param [Hash<Symbol,Object>] config The default configuration options to use when fetching secrets
121
+ #
122
+ def with_secret_config(**config)
123
+ raise ArgumentError, "You must pass a block to #with_secret_config" unless block_given?
124
+
125
+ begin
126
+ old_config = default_secret_config
127
+ # Use "public" API for input validation
128
+ default_secret_config(**config)
129
+ yield
130
+ ensure
131
+ # Use "private" API so we can set back to nil
132
+ run_context.default_secret_config = old_config
133
+ end
134
+ end
135
+
24
136
  # Helper method which looks up a secret using the given service and configuration,
25
137
  # and returns the retrieved secret value.
26
138
  # This DSL providers a wrapper around [Chef::SecretFetcher]
@@ -49,11 +161,7 @@ class Chef
49
161
  #
50
162
  # value = secret(name: "test1", service: :aws_secrets_manager, version: "v1", config: { region: "us-west-1" })
51
163
  # log "My secret is #{value}"
52
- def secret(name: nil, version: nil, service: nil, config: {})
53
- Chef::Log.warn <<~EOM.gsub("\n", " ")
54
- The secrets Chef Infra language helper is currently in beta. If you have feedback or you would
55
- like to be part of the future design of this helper e-mail us at secrets_management_beta@progress.com"
56
- EOM
164
+ def secret(name: nil, version: nil, service: default_secret_service, config: default_secret_config)
57
165
  sensitive(true) if is_a?(Chef::Resource)
58
166
  Chef::SecretFetcher.for_service(service, config, run_context).fetch(name, version)
59
167
  end
@@ -31,6 +31,12 @@ class Chef
31
31
 
32
32
  checksum.slice(0, 6)
33
33
  end
34
+
35
+ def checksum_match?(ref_checksum, diff_checksum)
36
+ return false if ref_checksum.nil? || diff_checksum.nil?
37
+
38
+ ref_checksum.casecmp?(diff_checksum)
39
+ end
34
40
  end
35
41
  end
36
42
  end
@@ -274,6 +274,12 @@ class Chef
274
274
  result
275
275
  end
276
276
 
277
+ # This method returns list of sensitive properties
278
+ # @return [Array<Property>] All sensitive properties.
279
+ def sensitive_properties
280
+ properties.values.empty? ? [] : properties.values.select(&:sensitive?)
281
+ end
282
+
277
283
  # Returns the name of the name property. Returns nil if there is no name property.
278
284
  #
279
285
  # @return [Symbol] the name property for this resource
@@ -452,17 +452,34 @@ class Chef
452
452
  # method-style access to attributes (has to come after the prepended ImmutablizeHash)
453
453
 
454
454
  def read(*path)
455
- merged_attributes.read(*path)
455
+ if path[0].nil?
456
+ Chef::Log.warn "Calling node.read() without any path argument is very slow, probably a bug, and should be avoided"
457
+ merged_attributes.read(*path) # re-merges everything, slow edge case
458
+ else
459
+ self[path[0]] unless path[0].nil? # force deep_merge_cache key construction if necessary
460
+ deep_merge_cache.read(*path)
461
+ end
456
462
  end
457
463
 
458
464
  alias :dig :read
459
465
 
460
466
  def read!(*path)
461
- merged_attributes.read!(*path)
467
+ if path[0].nil?
468
+ Chef::Log.warn "Calling node.read!() without any path argument is very slow, probably a bug, and should be avoided"
469
+ merged_attributes.read!(*path) # re-merges everything, slow edge case
470
+ else
471
+ self[path[0]] unless path[0].nil? # force deep_merge_cache key construction if necessary
472
+ deep_merge_cache.read!(*path)
473
+ end
462
474
  end
463
475
 
464
476
  def exist?(*path)
465
- merged_attributes.exist?(*path)
477
+ if path[0].nil?
478
+ true
479
+ else
480
+ self[path[0]] unless path[0].nil? # force deep_merge_cache key construction if necessary
481
+ deep_merge_cache.exist?(*path)
482
+ end
466
483
  end
467
484
 
468
485
  def write(level, *args, &block)
@@ -30,7 +30,7 @@ class Chef
30
30
  @merged_attributes = nil
31
31
  @combined_override = nil
32
32
  @combined_default = nil
33
- @deep_merge_cache = {}
33
+ @deep_merge_cache = Chef::Node::ImmutableMash.new
34
34
  end
35
35
 
36
36
  # Invalidate a key in the deep_merge_cache. If called with nil, or no arg, this will invalidate
@@ -39,9 +39,9 @@ class Chef
39
39
  # must invalidate the entire cache and re-deep-merge the entire node object.
40
40
  def reset_cache(path = nil)
41
41
  if path.nil?
42
- deep_merge_cache.clear
42
+ deep_merge_cache.regular_clear
43
43
  else
44
- deep_merge_cache.delete(path.to_s)
44
+ deep_merge_cache.regular_delete(path.to_s)
45
45
  end
46
46
  end
47
47
 
@@ -53,7 +53,7 @@ class Chef
53
53
  deep_merge_cache[key.to_s]
54
54
  else
55
55
  # save all the work of computing node[key]
56
- deep_merge_cache[key.to_s] = merged_attributes(key)
56
+ deep_merge_cache.internal_set(key.to_s, merged_attributes(key))
57
57
  end
58
58
  ret = ret.call while ret.is_a?(::Chef::DelayedEvaluator)
59
59
  ret
@@ -248,8 +248,7 @@ class Chef
248
248
  end
249
249
 
250
250
  def api_service
251
- @api_service ||= Chef::ServerAPI.new(config[:chef_server_url],
252
- { version_class: Chef::CookbookManifestVersions })
251
+ @api_service ||= Chef::ServerAPI.new(config[:chef_server_url], version_class: Chef::CookbookManifestVersions )
253
252
  end
254
253
 
255
254
  def config
@@ -507,7 +507,7 @@ class Chef
507
507
  # @api private
508
508
  def api_service
509
509
  @api_service ||= Chef::ServerAPI.new(config[:chef_server_url],
510
- { version_class: Chef::CookbookManifestVersions })
510
+ version_class: Chef::CookbookManifestVersions)
511
511
  end
512
512
 
513
513
  # @api private
@@ -336,7 +336,7 @@ class Chef
336
336
  end
337
337
 
338
338
  def do_validate_content
339
- if new_resource.checksum && tempfile && ( new_resource.checksum != tempfile_checksum )
339
+ if new_resource.checksum && tempfile && !checksum_match?(new_resource.checksum, tempfile_checksum)
340
340
  raise Chef::Exceptions::ChecksumMismatch.new(short_cksum(new_resource.checksum), short_cksum(tempfile_checksum))
341
341
  end
342
342
 
@@ -450,7 +450,7 @@ class Chef
450
450
 
451
451
  def contents_changed?
452
452
  logger.trace "calculating checksum of #{tempfile.path} to compare with #{current_resource.checksum}"
453
- tempfile_checksum != current_resource.checksum
453
+ !checksum_match?(tempfile_checksum, current_resource.checksum)
454
454
  end
455
455
 
456
456
  def tempfile
@@ -130,6 +130,21 @@ class Chef
130
130
  # install from, but like the rubygem provider's sources which are more like repos.
131
131
  def check_resource_semantics!; end
132
132
 
133
+ def self.get_choco_version
134
+ @get_choco_version ||= powershell_exec!("choco --version").result
135
+ end
136
+
137
+ # Choco V2 uses 'Search' for remote repositories and 'List' for local packages
138
+ def self.query_command
139
+ return "list" if get_choco_version.match?(/^1/)
140
+
141
+ "search"
142
+ end
143
+
144
+ def query_command
145
+ self.class.query_command
146
+ end
147
+
133
148
  private
134
149
 
135
150
  def version_compare(v1, v2)
@@ -225,7 +240,7 @@ class Chef
225
240
  package_name_array.each do |pkg|
226
241
  available_versions =
227
242
  begin
228
- cmd = [ "list", "-r", pkg ]
243
+ cmd = [ query_command, "-r", pkg ]
229
244
  cmd += common_options
230
245
  cmd.push( new_resource.list_options ) if new_resource.list_options
231
246
 
@@ -242,6 +257,8 @@ class Chef
242
257
  # Installed packages in chocolatey as a Hash of names mapped to versions
243
258
  # (names are downcased for case-insensitive matching)
244
259
  #
260
+ # Beginning with Choco 2.0, "list" returns local packages only while "search" returns packages from external package sources
261
+ #
245
262
  # @return [Hash] name-to-version mapping of installed packages
246
263
  def installed_packages
247
264
  @installed_packages ||= Hash[*parse_list_output("list", "-l", "-r").flatten]
@@ -56,7 +56,7 @@ class Chef
56
56
  names.each_with_index do |name, index|
57
57
  cmd = powershell_exec(build_powershell_package_command("Install-Package '#{name}'", versions[index]), timeout: new_resource.timeout)
58
58
  next if cmd.nil?
59
- raise Chef::Exceptions::PowershellCmdletException, "Failed to install package due to catalog signing error, use skip_publisher_check to force install" if /SkipPublisherCheck/.match?(cmd.error)
59
+ raise Chef::Exceptions::PowershellCmdletException, "Failed to install package due to catalog signing error, use skip_publisher_check to force install" if /SkipPublisherCheck/.match?(cmd.error!)
60
60
  end
61
61
  end
62
62
 
@@ -214,7 +214,7 @@ class Chef
214
214
  def install(gem_dependency, options = {})
215
215
  with_gem_sources(*options.delete(:sources)) do
216
216
  with_correct_verbosity do
217
- dependency_installer(options).install(gem_dependency)
217
+ dependency_installer(**options).install(gem_dependency)
218
218
  end
219
219
  end
220
220
  end
@@ -228,7 +228,7 @@ class Chef
228
228
  def uninstall(gem_name, gem_version = nil, opts = {})
229
229
  gem_version ? opts[:version] = gem_version : opts[:all] = true
230
230
  with_correct_verbosity do
231
- uninstaller(gem_name, opts).uninstall
231
+ uninstaller(gem_name, **opts).uninstall
232
232
  end
233
233
  end
234
234
 
@@ -240,12 +240,12 @@ class Chef
240
240
  yield
241
241
  end
242
242
 
243
- def dependency_installer(opts = {})
244
- Gem::DependencyInstaller.new(opts)
243
+ def dependency_installer(**opts)
244
+ Gem::DependencyInstaller.new(**opts)
245
245
  end
246
246
 
247
- def uninstaller(gem_name, opts = {})
248
- Gem::Uninstaller.new(gem_name, DEFAULT_UNINSTALLER_OPTS.merge(opts))
247
+ def uninstaller(gem_name, **opts)
248
+ Gem::Uninstaller.new(gem_name, **DEFAULT_UNINSTALLER_OPTS.merge(opts))
249
249
  end
250
250
 
251
251
  private
@@ -38,7 +38,7 @@ class Chef
38
38
  def define_resource_requirements
39
39
  if new_resource.checksum
40
40
  requirements.assert(:install) do |a|
41
- a.assertion { new_resource.checksum == checksum(source_location) }
41
+ a.assertion { checksum_match?(new_resource.checksum, checksum(source_location)) }
42
42
  a.failure_message Chef::Exceptions::Package, "Checksum on resource (#{short_cksum(new_resource.checksum)}) does not match checksum on content (#{short_cksum(source_location)})"
43
43
  end
44
44
  end
@@ -178,7 +178,20 @@ class Chef
178
178
  #
179
179
  # @api private
180
180
  def combine_args(provides, version, arch)
181
- provides = provides.dup
181
+ provides = provides.to_s.strip
182
+ version = if !version.nil? && !version.empty?
183
+ version.to_s.strip
184
+ end
185
+ arch = if !arch.nil? && !arch.empty?
186
+ arch.to_s.strip
187
+ end
188
+ if version =~ /^[><=]/
189
+ if arch
190
+ return { "provides" => "#{provides}.#{arch} #{version}" }
191
+ else
192
+ return { "provides" => "#{provides} #{version}" }
193
+ end
194
+ end
182
195
  maybe_arch = provides.rpartition(".").last
183
196
  if is_arch?(maybe_arch)
184
197
  arch = maybe_arch
@@ -183,7 +183,7 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
183
183
  end
184
184
 
185
185
  converge_by("create service #{new_resource.service_name}") do
186
- Win32::Service.new(windows_service_config)
186
+ Win32::Service.new(**windows_service_config)
187
187
  end
188
188
 
189
189
  converge_delayed_start
@@ -209,7 +209,7 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
209
209
  converge_if_changed :service_type, :startup_type, :error_control,
210
210
  :binary_path_name, :load_order_group, :dependencies,
211
211
  :run_as_user, :display_name, :description do
212
- Win32::Service.configure(windows_service_config(:configure))
212
+ Win32::Service.configure(**windows_service_config(:configure))
213
213
  end
214
214
 
215
215
  converge_delayed_start
@@ -268,7 +268,7 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
268
268
  password: new_resource.run_as_password,
269
269
  }.reject { |k, v| v.nil? || v.length == 0 }
270
270
 
271
- Win32::Service.configure(new_config)
271
+ Win32::Service.configure(**new_config)
272
272
  logger.info "#{new_resource} configured."
273
273
 
274
274
  grant_service_logon(new_resource.run_as_user) if new_resource.run_as_user != "localsystem"
@@ -395,7 +395,7 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
395
395
  config[:service_name] = new_resource.service_name
396
396
  config[:delayed_start] = new_resource.delayed_start ? 1 : 0
397
397
 
398
- Win32::Service.configure(config)
398
+ Win32::Service.configure(**config)
399
399
  end
400
400
  end
401
401
 
@@ -78,11 +78,11 @@ class Chef
78
78
  end
79
79
 
80
80
  def create_user
81
- @net_user.add(set_options)
81
+ @net_user.add(**set_options)
82
82
  end
83
83
 
84
84
  def manage_user
85
- @net_user.update(set_options)
85
+ @net_user.update(**set_options)
86
86
  end
87
87
 
88
88
  def remove_user
@@ -117,7 +117,11 @@ class Chef
117
117
  new_val = new_resource.send(user_attrib)
118
118
  cur_val = current_resource.send(user_attrib)
119
119
  if !new_val.nil? && new_val.to_s != cur_val.to_s
120
- @change_desc << "change #{user_attrib} from #{cur_val} to #{new_val}"
120
+ if user_attrib.to_s == "password" && new_resource.sensitive
121
+ @change_desc << "change #{user_attrib} from ******** to ********"
122
+ else
123
+ @change_desc << "change #{user_attrib} from #{cur_val} to #{new_val}"
124
+ end
121
125
  end
122
126
  end
123
127
 
@@ -209,6 +209,10 @@ class Chef
209
209
  description: %q(An array of hashes that contain a report handler class and the arguments to pass to that class on initialization. The hash should include `class` and `argument` keys where `class` is a String and `argument` is an array of quoted String values. For example: `[{'class' => 'MyHandler', %w('"argument1"', '"argument2"')}]`),
210
210
  default: []
211
211
 
212
+ property :rubygems_url, [String, Array],
213
+ description: "The location to source rubygems. It can be set to a string or array of strings for URIs to set as rubygems sources. This allows individuals to setup an internal mirror of rubygems for “airgapped” environments.",
214
+ introduced: "17.11"
215
+
212
216
  property :exception_handlers, Array,
213
217
  description: %q(An array of hashes that contain a exception handler class and the arguments to pass to that class on initialization. The hash should include `class` and `argument` keys where `class` is a String and `argument` is an array of quoted String values. For example: `[{'class' => 'MyHandler', %w('"argument1"', '"argument2"')}]`),
214
218
  default: []
@@ -297,6 +301,7 @@ class Chef
297
301
  policy_group: new_resource.policy_group,
298
302
  policy_name: new_resource.policy_name,
299
303
  report_handlers: format_handler(new_resource.report_handlers),
304
+ rubygems_url: new_resource.rubygems_url,
300
305
  ssl_verify_mode: new_resource.ssl_verify_mode,
301
306
  start_handlers: format_handler(new_resource.start_handlers),
302
307
  additional_config: new_resource.additional_config,
@@ -113,8 +113,11 @@ class Chef
113
113
  end
114
114
 
115
115
  requirements.assert(:all_actions) do |a|
116
- # RHEL/CentOS type platforms don't have locale-gen
117
- a.assertion { shell_out("locale-gen") }
116
+ a.assertion do
117
+ # RHEL/CentOS type platforms don't have locale-gen
118
+ # Windows has locale-gen as part of the install, but not in the path
119
+ which("locale-gen") || windows?
120
+ end
118
121
  a.failure_message(Chef::Exceptions::ProviderNotFound, "The locale resource requires the locale-gen tool")
119
122
  end
120
123
  end