chef 17.9.52-universal-mingw32 → 17.10.68-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/Rakefile +2 -2
  4. data/chef-universal-mingw32.gemspec +2 -1
  5. data/chef.gemspec +5 -5
  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/node/attribute.rb +20 -3
  14. data/lib/chef/node/mixin/deep_merge_cache.rb +4 -4
  15. data/lib/chef/policy_builder/expand_node_object.rb +1 -2
  16. data/lib/chef/policy_builder/policyfile.rb +1 -1
  17. data/lib/chef/provider/file.rb +2 -2
  18. data/lib/chef/provider/package/powershell.rb +1 -1
  19. data/lib/chef/provider/package/rubygems.rb +6 -6
  20. data/lib/chef/provider/package/windows.rb +1 -1
  21. data/lib/chef/provider/package/yum/python_helper.rb +14 -1
  22. data/lib/chef/provider/service/windows.rb +4 -4
  23. data/lib/chef/provider/user/windows.rb +2 -2
  24. data/lib/chef/resource/chef_client_config.rb +5 -0
  25. data/lib/chef/resource/locale.rb +1 -1
  26. data/lib/chef/resource/rhsm_register.rb +19 -0
  27. data/lib/chef/resource/support/client.erb +1 -2
  28. data/lib/chef/resource/windows_certificate.rb +54 -43
  29. data/lib/chef/resource/windows_pagefile.rb +28 -21
  30. data/lib/chef/resource/windows_user_privilege.rb +36 -26
  31. data/lib/chef/run_context.rb +16 -0
  32. data/lib/chef/secret_fetcher/hashi_vault.rb +1 -1
  33. data/lib/chef/version.rb +1 -1
  34. data/lib/chef/win32/version.rb +2 -1
  35. data/spec/data/trusted_certs/opscode.pem +33 -54
  36. data/spec/functional/resource/dnf_package_spec.rb +15 -0
  37. data/spec/functional/resource/windows_certificate_spec.rb +41 -13
  38. data/spec/functional/resource/windows_font_spec.rb +1 -1
  39. data/spec/functional/resource/windows_pagefile_spec.rb +31 -4
  40. data/spec/functional/resource/yum_package_spec.rb +15 -0
  41. data/spec/functional/shell_spec.rb +6 -0
  42. data/spec/unit/client_spec.rb +6 -3
  43. data/spec/unit/daemon_spec.rb +1 -5
  44. data/spec/unit/dsl/secret_spec.rb +127 -23
  45. data/spec/unit/mixin/checksum_spec.rb +28 -0
  46. data/spec/unit/provider/package/rubygems_spec.rb +1 -1
  47. data/spec/unit/resource/chef_client_config_spec.rb +8 -0
  48. data/spec/unit/run_context_spec.rb +16 -0
  49. metadata +43 -29
  50. /data/spec/functional/assets/yumrepo/repodata/{4632d67cb92636e7575d911c24f0e04d3505a944e97c483abe0c3e73a7c62d33-filelists.sqlite.bz2 → 01a3b-filelists.sqlite.bz2} +0 -0
  51. /data/spec/functional/assets/yumrepo/repodata/{bdb4f5f1492a3b9532f22c43110a81500dd744f23da0aec5c33b2a41317c737d-filelists.xml.gz → 401dc-filelists.xml.gz} +0 -0
  52. /data/spec/functional/assets/yumrepo/repodata/{a845d418f919d2115ab95a56b2c76f6825ad0d0bede49181a55c04f58995d057-primary.sqlite.bz2 → 5dc1e-primary.sqlite.bz2} +0 -0
  53. /data/spec/functional/assets/yumrepo/repodata/{74599b793e54d877323837d2d81a1c3c594c44e4335f9528234bb490f7b9b439-other.xml.gz → 6bf96-other.xml.gz} +0 -0
  54. /data/spec/functional/assets/yumrepo/repodata/{af9b7cf9ef23bd7b43068d74a460f3b5d06753d638e58e4a0c9edc35bfb9cdc4-other.sqlite.bz2 → 7c365-other.sqlite.bz2} +0 -0
  55. /data/spec/functional/assets/yumrepo/repodata/{c10d1d34ce99e02f12ec96ef68360543ab1bb7c3cb81a4a2bf78df7d8597e9df-primary.xml.gz → dabe2-primary.xml.gz} +0 -0
@@ -56,10 +56,34 @@ describe Chef::Resource::WindowsCertificate, :windows_only do
56
56
  let(:store) { "Chef-Functional-Test" }
57
57
  let(:store_name) { "MY" }
58
58
  let(:store_location) { "LocalMachine" }
59
- let(:download_cert_url) { "https://testingchef.blob.core.windows.net/files/test.cer" }
59
+ let(:test_cert_body) do
60
+ <<~CERT
61
+ -----BEGIN CERTIFICATE-----
62
+ MIIDQTCCAimgAwIBAgIQX3zqNCJbsKlEvzCz3Z9aNDANBgkqhkiG9w0BAQsFADAh
63
+ MR8wHQYDVQQDDBZ3d3cuZHVtbXljaGVmdGVzdHMuY29tMCAXDTIwMDMwNTEwMjcw
64
+ NVoYDzIxMjAwMzA1MTAzNzA2WjAhMR8wHQYDVQQDDBZ3d3cuZHVtbXljaGVmdGVz
65
+ dHMuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtuYKDb6woWIH
66
+ HPPOrcVpgJFVxbkjgk+tsYwbIiqR9jtRaKE6nM/awOgn9/dFF4k8KB8Em0sUx7Vq
67
+ J3YhK2N2cAacgP2Frqqf5znpNBBOg968RoZzGx0EiXFvLsqC4y8ggApWTbMXPRk4
68
+ 1a7GlpUpSqI3y5cLeEbzwGQKu8I1I+v7P2fTlnJPHarM7sBbL8bieukkFHYu78iV
69
+ u1wpKOCCfs5DTmJu8WN+z1Mar9vyrWMBlt2wBBgNHPz5mcXUzJHTzaI/D9RGgBgF
70
+ V0IkNqISx/IzR62jjj2g6MgTH4G/0mM6O5sxduM4yGmWZNZpVzh0yMLgH619MZlj
71
+ SMQIN3U/SQIDAQABo3MwcTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB
72
+ BQUHAwIGCCsGAQUFBwMBMCEGA1UdEQQaMBiCFnd3dy5kdW1teWNoZWZ0ZXN0cy5j
73
+ b20wHQYDVR0OBBYEFHwS3gs03m6RcpR+66u4OqGiZdYnMA0GCSqGSIb3DQEBCwUA
74
+ A4IBAQCFHqMjHUfBZahIsKHQIcFCbC1NFh1ZHlJKZzrRBRwRzX19OttHGMyLpDd6
75
+ tM9Ac6LLR8S4QIWg+HF3IrkN+vfTRDZAccj+tIwBRstmdsEz/rAJ79Vb/00mXZQx
76
+ 0FPiBDR3hE7On2oo24DU8kJP3v6TrunwtIomVGqrrkwZzvxqyW+WJMB2shGNFw5J
77
+ mKYBiiXsHl4Bi7V4zhXssrLp877sqpNLeXloXBmAlT39SwQTP9ImZaV5R6udqlvo
78
+ Gfgm5PH/WeK6MV3n5ik0v1rS0LwR2o82WlIB6a4iSEbzY3qSLsWOwt8o5QjAVzCR
79
+ tNdbdS3U8nrG73iA2clmF57ARQWC
80
+ -----END CERTIFICATE-----
81
+ CERT
82
+ end
60
83
  let(:cert_output_path) { ::File.join(Chef::Config[:file_cache_path], "output.cer") }
61
84
  let(:pfx_output_path) { ::File.join(Chef::Config[:file_cache_path], "output.pfx") }
62
85
  let(:key_output_path) { ::File.join(Chef::Config[:file_cache_path], "output.key") }
86
+ let(:download_cert_url) { "https://testingchef.blob.core.windows.net/files/test.cer" }
63
87
  let(:cer_path) { File.join(CHEF_SPEC_DATA, "windows_certificates", "test.cer") }
64
88
  let(:base64_path) { File.join(CHEF_SPEC_DATA, "windows_certificates", "base64_test.cer") }
65
89
  let(:pem_path) { File.join(CHEF_SPEC_DATA, "windows_certificates", "test.pem") }
@@ -89,7 +113,9 @@ describe Chef::Resource::WindowsCertificate, :windows_only do
89
113
 
90
114
  end
91
115
 
92
- after { delete_store }
116
+ after do
117
+ delete_store
118
+ end
93
119
 
94
120
  describe "action: create" do
95
121
  it "starts with no certificates" do
@@ -126,6 +152,7 @@ describe Chef::Resource::WindowsCertificate, :windows_only do
126
152
  end
127
153
 
128
154
  it "can add a certificate from a valid url" do
155
+ stub_request(:get, download_cert_url).to_return(body: test_cert_body)
129
156
  resource.source = download_cert_url
130
157
  resource.run_action(:create)
131
158
 
@@ -195,7 +222,7 @@ describe Chef::Resource::WindowsCertificate, :windows_only do
195
222
  create_store
196
223
  end
197
224
  it "fails with no certificates in the store" do
198
- expect(Chef::Log).to receive(:info).with("Certificate not found")
225
+ expect(Chef::Log).to receive(:info).with("Certificate not valid")
199
226
 
200
227
  resource.source = tests_thumbprint
201
228
  resource.run_action(:verify)
@@ -219,7 +246,7 @@ describe Chef::Resource::WindowsCertificate, :windows_only do
219
246
  end
220
247
 
221
248
  it "fails with an invalid thumbprint" do
222
- expect(Chef::Log).to receive(:info).with("Certificate not found")
249
+ expect(Chef::Log).to receive(:info).with("Certificate not valid")
223
250
 
224
251
  resource.source = others_thumbprint
225
252
  resource.run_action(:verify)
@@ -253,7 +280,7 @@ describe Chef::Resource::WindowsCertificate, :windows_only do
253
280
  end
254
281
 
255
282
  it "fails with an invalid thumbprint" do
256
- expect(Chef::Log).to receive(:info).with("Certificate not found")
283
+ expect(Chef::Log).to receive(:info).with("Certificate not valid")
257
284
 
258
285
  resource.source = others_thumbprint
259
286
  resource.run_action(:verify)
@@ -265,11 +292,11 @@ describe Chef::Resource::WindowsCertificate, :windows_only do
265
292
 
266
293
  describe "action: fetch" do
267
294
  context "with no certificate in the store" do
268
- it "throws an error with no certificates in the store" do
269
- expect(Chef::Log).not_to receive(:info)
295
+ it "logs a debug error with no certificates in the store" do
296
+ expect(Chef::Log).to receive(:debug).with("Certificate Not Found")
270
297
  resource.source = others_thumbprint
271
298
  resource.output_path = cert_output_path
272
- expect { resource.run_action :fetch }.to raise_error(ArgumentError)
299
+ resource.run_action(:fetch)
273
300
  end
274
301
  end
275
302
 
@@ -288,7 +315,7 @@ describe Chef::Resource::WindowsCertificate, :windows_only do
288
315
  end
289
316
 
290
317
  it "fails with an invalid thumbprint" do
291
- expect(Chef::Log).not_to receive(:info)
318
+ expect(Chef::Log).to receive(:debug).with("Certificate Not Found")
292
319
 
293
320
  resource.source = others_thumbprint
294
321
 
@@ -296,7 +323,7 @@ describe Chef::Resource::WindowsCertificate, :windows_only do
296
323
  path = File.join(dir, "test.pem")
297
324
 
298
325
  resource.output_path = path
299
- expect { resource.run_action :fetch }.to raise_error(ArgumentError)
326
+ resource.run_action(:fetch)
300
327
  end
301
328
 
302
329
  end
@@ -340,9 +367,10 @@ describe Chef::Resource::WindowsCertificate, :windows_only do
340
367
  end
341
368
 
342
369
  describe "action: delete" do
343
- it "throws an argument error when attempting to delete a certificate that doesn't exist" do
370
+ it "logs an error when attempting to delete a certificate that doesn't exist" do
371
+ expect(Chef::Log).to receive(:debug).with("Certificate Not Found")
344
372
  resource.source = tests_thumbprint
345
- expect { resource.run_action :delete }.to raise_error(ArgumentError)
373
+ resource.run_action(:delete)
346
374
  end
347
375
 
348
376
  it "deletes an existing certificate while leaving other certificates alone" do
@@ -360,7 +388,7 @@ describe Chef::Resource::WindowsCertificate, :windows_only do
360
388
  expect(certificate_count).to eq(1)
361
389
  expect(resource).to be_updated_by_last_action
362
390
 
363
- expect { resource.run_action :delete }.to raise_error(ArgumentError)
391
+ expect { resource.run_action :delete }.not_to raise_error
364
392
  expect(certificate_count).to eq(1)
365
393
  expect(resource).not_to be_updated_by_last_action
366
394
 
@@ -18,7 +18,7 @@
18
18
 
19
19
  require "spec_helper"
20
20
 
21
- describe Chef::Resource::WindowsFont, :windows_only do
21
+ describe Chef::Resource::WindowsFont, :windows_only, :broken do # these tests hang on Chef-16 and Chef-17 in the verify-pipline.
22
22
  let(:resource_name) { "Playmaker.ttf" }
23
23
  let(:resource_source) { "https://www.wfonts.com/download/data/2020/05/06/playmaker/Playmaker.ttf" }
24
24
 
@@ -40,13 +40,32 @@ describe Chef::Resource::WindowsPagefile, :windows_only do
40
40
  new_resource
41
41
  end
42
42
 
43
+ def set_automatic_managed_to_false
44
+ powershell_code = <<~EOH
45
+ $computersys = Get-WmiObject Win32_ComputerSystem -EnableAllPrivileges;
46
+ $computersys.AutomaticManagedPagefile = $False;
47
+ $computersys.Put();
48
+ EOH
49
+ powershell_exec!(powershell_code)
50
+ end
51
+
52
+ def set_automatic_managed_to_true
53
+ powershell_code = <<~EOH
54
+ $computersys = Get-WmiObject Win32_ComputerSystem -EnableAllPrivileges;
55
+ $computersys.AutomaticManagedPagefile = $True;
56
+ $computersys.Put();
57
+ EOH
58
+ powershell_exec!(powershell_code)
59
+ end
60
+
43
61
  describe "Setting Up Pagefile Management" do
44
62
  context "Disable Automatic Management" do
45
- it "Disables Automatic Management" do
63
+ it "Verifies Automatic Management is Disabled" do
64
+ set_automatic_managed_to_false
46
65
  subject.path c_path
47
66
  subject.automatic_managed false
48
67
  subject.run_action(:set)
49
- expect(subject).to be_updated_by_last_action
68
+ expect(subject).not_to be_updated_by_last_action
50
69
  end
51
70
 
52
71
  it "Enable Automatic Management " do
@@ -55,6 +74,14 @@ describe Chef::Resource::WindowsPagefile, :windows_only do
55
74
  subject.run_action(:set)
56
75
  expect(subject).to be_updated_by_last_action
57
76
  end
77
+
78
+ it "Disables Automatic Management" do
79
+ set_automatic_managed_to_true
80
+ subject.path c_path
81
+ subject.automatic_managed false
82
+ subject.run_action(:set)
83
+ expect(subject).to be_updated_by_last_action
84
+ end
58
85
  end
59
86
  end
60
87
 
@@ -69,8 +96,8 @@ describe Chef::Resource::WindowsPagefile, :windows_only do
69
96
  context "Update a pagefile" do
70
97
  it "Changes a pagefile to use custom sizes" do
71
98
  subject.path c_path
72
- subject.initial_size 20000
73
- subject.maximum_size 80000
99
+ subject.initial_size 128
100
+ subject.maximum_size 512
74
101
  subject.run_action(:set)
75
102
  expect(subject).to be_updated_by_last_action
76
103
  end
@@ -754,6 +754,21 @@ describe Chef::Resource::YumPackage, :requires_root, external: exclude_test do
754
754
  action :install
755
755
  end.should_not_be_updated
756
756
  end
757
+
758
+ it "works with constraints in the version property" do
759
+ flush_cache
760
+ yum_package "chef_rpm" do
761
+ version ">= 1.10"
762
+ options default_options
763
+ action :install
764
+ end.should_be_updated
765
+ expect_matching_installed_version("^chef_rpm-1.10-1.#{pkg_arch}$")
766
+ yum_package "chef_rpm" do
767
+ version ">= 1.10"
768
+ options default_options
769
+ action :install
770
+ end.should_not_be_updated
771
+ end
757
772
  end
758
773
 
759
774
  context "with source arguments" do
@@ -80,6 +80,12 @@ describe Shell do
80
80
  # so hide the require here
81
81
 
82
82
  require "pty"
83
+
84
+ # FIXME this is temporary... Solaris envs have TERM set to unknown
85
+ # and the value isn't propagating from the build environment TERM
86
+ # variable
87
+ ENV["TERM"] = "vt100" if ["", "unknown"].include?(ENV["TERM"].to_s)
88
+
83
89
  config = File.expand_path("shef-config.rb", CHEF_SPEC_DATA)
84
90
  reader, writer, pid = PTY.spawn("bundle exec chef-shell --no-multiline --no-singleline --no-colorize -c #{config} #{options}")
85
91
  read_until(reader, "chef (#{Chef::VERSION})>")
@@ -311,14 +311,17 @@ describe Chef::Client do
311
311
  describe "eol release warning" do
312
312
  it "warns when running an EOL release" do
313
313
  stub_const("Chef::VERSION", 15)
314
- allow(Time).to receive(:now).and_return(Time.new(2021, 5, 1, 5))
315
- expect(logger).to receive(:warn).with(/This release of.*became end of life \(EOL\) on May 1st 2021/)
314
+ # added a call to client because Time.now gets invoked multiple times during instantiation. Don't mock Time until after client initialized
315
+ client
316
+ expect(Time).to receive(:now).and_return(Time.new(2021, 5, 1, 5))
317
+ allow(client).to receive(:eol_override).and_return(false)
318
+ expect(logger).to receive(:warn).with("This release of Chef Infra Client became end of life (EOL) on May 01, 2021. Please update to a supported release to receive new features, bug fixes, and security updates.")
316
319
  client.warn_if_eol
317
320
  end
318
321
 
319
322
  it "does not warn when running an non-EOL release" do
320
323
  stub_const("Chef::VERSION", 15)
321
- allow(Time).to receive(:now).and_return(Time.new(2021, 4, 31))
324
+ allow(Time).to receive(:now).and_return(Time.new(2021, 4, 30))
322
325
  expect(logger).to_not receive(:warn).with(/became end of life/)
323
326
  client.warn_if_eol
324
327
  end
@@ -170,11 +170,7 @@ describe Chef::Daemon do
170
170
 
171
171
  it "should log an appropriate error message and fail miserably" do
172
172
  allow(Process).to receive(:initgroups).and_raise(Errno::EPERM)
173
- error = "Operation not permitted"
174
- if RUBY_PLATFORM.match("solaris2") || RUBY_PLATFORM.match("aix")
175
- error = "Not owner"
176
- end
177
- expect(Chef::Application).to receive(:fatal!).with("Permission denied when trying to change 999:999 to 501:20. #{error}")
173
+ expect(Chef::Application).to receive(:fatal!).with(/Permission denied when trying to change 999:999 to 501:20/)
178
174
  Chef::Daemon._change_privilege(testuser)
179
175
  end
180
176
  end
@@ -17,11 +17,14 @@
17
17
  #
18
18
 
19
19
  require "spec_helper"
20
+ require "chef/exceptions"
20
21
  require "chef/dsl/secret"
21
22
  require "chef/secret_fetcher/base"
23
+
22
24
  class SecretDSLTester
23
25
  include Chef::DSL::Secret
24
- # Because DSL is invoked in the context of a recipe,
26
+
27
+ # Because DSL is invoked in the context of a recipe or attribute file
25
28
  # we expect run_context to always be available when SecretFetcher::Base
26
29
  # requests it - making it safe to mock here
27
30
  def run_context
@@ -37,35 +40,136 @@ end
37
40
 
38
41
  describe Chef::DSL::Secret do
39
42
  let(:dsl) { SecretDSLTester.new }
40
- it "responds to 'secret'" do
41
- expect(dsl.respond_to?(:secret)).to eq true
43
+ let(:run_context) { Chef::RunContext.new(Chef::Node.new, {}, Chef::EventDispatch::Dispatcher.new) }
44
+
45
+ before do
46
+ allow(dsl).to receive(:run_context).and_return(run_context)
42
47
  end
43
48
 
44
- it "uses SecretFetcher.for_service to find the fetcher" do
45
- substitute_fetcher = SecretFetcherImpl.new({}, nil)
46
- expect(Chef::SecretFetcher).to receive(:for_service).with(:example, {}, nil).and_return(substitute_fetcher)
47
- expect(substitute_fetcher).to receive(:fetch).with("key1", nil)
48
- dsl.secret(name: "key1", service: :example, config: {})
49
+ %w{
50
+ secret
51
+ default_secret_service
52
+ default_secret_config
53
+ with_secret_service
54
+ with_secret_config
55
+ }.each do |m|
56
+ it "responds to ##{m}" do
57
+ expect(dsl.respond_to?(m)).to eq true
58
+ end
59
+ end
60
+
61
+ describe "#default_secret_service" do
62
+ let(:service) { :hashi_vault }
63
+
64
+ it "persists the service passed in as an argument" do
65
+ expect(dsl.default_secret_service).to eq(nil)
66
+ dsl.default_secret_service(service)
67
+ expect(dsl.default_secret_service).to eq(service)
68
+ end
69
+
70
+ it "returns run_context.default_secret_service value when no argument is given" do
71
+ run_context.default_secret_service = :my_thing
72
+ expect(dsl.default_secret_service).to eq(:my_thing)
73
+ end
74
+
75
+ it "raises exception when service given is not valid" do
76
+ stub_const("Chef::SecretFetcher::SECRET_FETCHERS", %i{service_a service_b})
77
+ expect { dsl.default_secret_service(:unknown_service) }.to raise_error(Chef::Exceptions::Secret::InvalidFetcherService)
78
+ end
49
79
  end
50
80
 
51
- it "resolves a secret when using the example fetcher" do
52
- secret_value = dsl.secret(name: "test1", service: :example, config: { "test1" => "secret value" })
53
- expect(secret_value).to eq "secret value"
81
+ describe "#with_secret_config" do
82
+ let(:service) { :hashi_vault }
83
+
84
+ it "sets the service for the scope of the block only" do
85
+ expect(dsl.default_secret_service).to eq(nil)
86
+ dsl.with_secret_service(service) do
87
+ expect(dsl.default_secret_service).to eq(service)
88
+ end
89
+ expect(dsl.default_secret_service).to eq(nil)
90
+ end
91
+
92
+ it "raises exception when block is not given" do
93
+ expect { dsl.with_secret_service(service) }.to raise_error(ArgumentError)
94
+ end
54
95
  end
55
96
 
56
- context "when used within a resource" do
57
- let(:run_context) {
58
- Chef::RunContext.new(Chef::Node.new,
59
- Chef::CookbookCollection.new(Chef::CookbookLoader.new(File.join(CHEF_SPEC_DATA, "cookbooks"))),
60
- Chef::EventDispatch::Dispatcher.new)
61
- }
62
-
63
- it "marks that resource as 'sensitive'" do
64
- recipe = Chef::Recipe.new("secrets", "test", run_context)
65
- recipe.zen_master "secret_test" do
66
- peace secret(name: "test1", service: :example, config: { "test1" => true })
97
+ describe "#default_secret_config" do
98
+ let(:config) { { my_key: "value" } }
99
+
100
+ it "persists the config passed in as argument" do
101
+ expect(dsl.default_secret_config).to eq({})
102
+ dsl.default_secret_config(**config)
103
+ expect(dsl.default_secret_config).to eq(config)
104
+ end
105
+
106
+ it "returns run_context.default_secret_config value when no argument is given" do
107
+ run_context.default_secret_config = { my_thing: "that" }
108
+ expect(dsl.default_secret_config).to eq({ my_thing: "that" })
109
+ end
110
+ end
111
+
112
+ describe "#with_secret_config" do
113
+ let(:config) { { my_key: "value" } }
114
+
115
+ it "sets the config for the scope of the block only" do
116
+ expect(dsl.default_secret_config).to eq({})
117
+ dsl.with_secret_config(**config) do
118
+ expect(dsl.default_secret_config).to eq(config)
67
119
  end
68
- expect(run_context.resource_collection.lookup("zen_master[secret_test]").sensitive).to eql(true)
120
+ expect(dsl.default_secret_config).to eq({})
121
+ end
122
+
123
+ it "raises exception when block is not given" do
124
+ expect { dsl.with_secret_config(**config) }.to raise_error(ArgumentError)
125
+ end
126
+ end
127
+
128
+ describe "#secret" do
129
+ it "uses SecretFetcher.for_service to find the fetcher" do
130
+ substitute_fetcher = SecretFetcherImpl.new({}, nil)
131
+ expect(Chef::SecretFetcher).to receive(:for_service).with(:example, {}, run_context).and_return(substitute_fetcher)
132
+ expect(substitute_fetcher).to receive(:fetch).with("key1", nil)
133
+ dsl.secret(name: "key1", service: :example, config: {})
134
+ end
135
+
136
+ it "resolves a secret when using the example fetcher" do
137
+ secret_value = dsl.secret(name: "test1", service: :example, config: { "test1" => "secret value" })
138
+ expect(secret_value).to eq "secret value"
139
+ end
140
+
141
+ context "when used within a resource" do
142
+ let(:run_context) {
143
+ Chef::RunContext.new(Chef::Node.new,
144
+ Chef::CookbookCollection.new(Chef::CookbookLoader.new(File.join(CHEF_SPEC_DATA, "cookbooks"))),
145
+ Chef::EventDispatch::Dispatcher.new)
146
+ }
147
+
148
+ it "marks that resource as 'sensitive'" do
149
+ recipe = Chef::Recipe.new("secrets", "test", run_context)
150
+ recipe.zen_master "secret_test" do
151
+ peace secret(name: "test1", service: :example, config: { "test1" => true })
152
+ end
153
+ expect(run_context.resource_collection.lookup("zen_master[secret_test]").sensitive).to eql(true)
154
+ end
155
+ end
156
+
157
+ it "passes default service to SecretFetcher.for_service" do
158
+ service = :example
159
+ dsl.default_secret_service(service)
160
+ substitute_fetcher = SecretFetcherImpl.new({}, nil)
161
+ expect(Chef::SecretFetcher).to receive(:for_service).with(service, {}, run_context).and_return(substitute_fetcher)
162
+ allow(substitute_fetcher).to receive(:fetch).with("key1", nil)
163
+ dsl.secret(name: "key1")
164
+ end
165
+
166
+ it "passes default config to SecretFetcher.for_service" do
167
+ config = { my_config: "value" }
168
+ dsl.default_secret_config(**config)
169
+ substitute_fetcher = SecretFetcherImpl.new({}, nil)
170
+ expect(Chef::SecretFetcher).to receive(:for_service).with(:example, config, run_context).and_return(substitute_fetcher)
171
+ allow(substitute_fetcher).to receive(:fetch).with("key1", nil)
172
+ dsl.secret(name: "key1", service: :example)
69
173
  end
70
174
  end
71
175
  end
@@ -51,4 +51,32 @@ describe Chef::Mixin::Checksum do
51
51
  end
52
52
  end
53
53
 
54
+ describe "checksum_match?" do
55
+ context "when checksum cases match" do
56
+ it "returns true" do
57
+ expect(@checksum_user.checksum_match?("u7ghbxikk3i9blsimmy2y2ionmxx", "u7ghbxikk3i9blsimmy2y2ionmxx")).to be true
58
+ end
59
+ end
60
+
61
+ context "when one checksum is uppercase and other is lowercase" do
62
+ it "returns true" do
63
+ expect(@checksum_user.checksum_match?("U7GHBXIKK3I9BLSIMMY2Y2IONMXX", "u7ghbxikk3i9blsimmy2y2ionmxx")).to be true
64
+ end
65
+ end
66
+
67
+ context "when checksums do not match" do
68
+ it "returns false" do
69
+ expect(@checksum_user.checksum_match?("u7ghbxikk3i9blsimmy2y2ionmxx", "09ee9c8cc70501763563bcf9c218")).to be false
70
+ end
71
+ end
72
+
73
+ context "when checksum is nil" do
74
+ it "returns false" do
75
+ expect(@checksum_user.checksum_match?("u7ghbxikk3i9blsimmy2y2ionmxx", nil)).to be false
76
+ expect(@checksum_user.checksum_match?(nil, "09ee9c8cc70501763563bcf9c218")).to be false
77
+ expect(@checksum_user.checksum_match?(nil, nil)).to be false
78
+ end
79
+ end
80
+ end
81
+
54
82
  end
@@ -143,7 +143,7 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do
143
143
  .to_return(status: 200, body: File.binread(File.join(CHEF_SPEC_DATA, "rubygems.org", "sexp_processor-4.15.1.gemspec.rz")))
144
144
 
145
145
  dep = Gem::Dependency.new("sexp_processor", ">= 0")
146
- expect(@gem_env.candidate_version_from_remote(dep, "https://rubygems2.org")).to be_kind_of(Gem::Version)
146
+ expect(@gem_env.candidate_version_from_remote(dep, "https://rubygems2.org")).to be_nil
147
147
  end
148
148
  end
149
149
 
@@ -134,4 +134,12 @@ describe Chef::Resource::ChefClientConfig do
134
134
  expect(provider.format_handler([{ "class" => "Foo", "arguments" => ["'one'", "two", "three"] }])).to eql(["Foo.new('one',two,three)"])
135
135
  end
136
136
  end
137
+
138
+ describe "rubygems_url property" do
139
+ it "accepts nil, a single URL, or an array of URLs" do
140
+ expect { resource.rubygems_url(nil) }.not_to raise_error
141
+ expect { resource.rubygems_url("https://rubygems.internal.example.com") }.not_to raise_error
142
+ expect { resource.rubygems_url(["https://rubygems.east.example.com", "https://rubygems.west.example.com"]) }.not_to raise_error
143
+ end
144
+ end
137
145
  end
@@ -53,6 +53,22 @@ describe Chef::RunContext do
53
53
  expect(run_context.node).to eq(node)
54
54
  end
55
55
 
56
+ it "responds to #default_secret_service" do
57
+ expect(run_context).to respond_to(:default_secret_service)
58
+ end
59
+
60
+ it "responds to #default_secret_config" do
61
+ expect(run_context).to respond_to(:default_secret_config)
62
+ end
63
+
64
+ it "#default_secret_service defaults to nil" do
65
+ expect(run_context.default_secret_service).to eq(nil)
66
+ end
67
+
68
+ it "#default_secret_config defaults to {}" do
69
+ expect(run_context.default_secret_config).to eq({})
70
+ end
71
+
56
72
  it "loads up node[:cookbooks]" do
57
73
  expect(run_context.node[:cookbooks]).to eql(
58
74
  {