chef 16.7.61 → 16.9.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -5
  3. data/README.md +2 -2
  4. data/chef.gemspec +12 -2
  5. data/lib/chef/application/base.rb +1 -1
  6. data/lib/chef/client.rb +3 -0
  7. data/lib/chef/compliance/default_attributes.rb +93 -0
  8. data/lib/chef/compliance/fetcher/automate.rb +69 -0
  9. data/lib/chef/compliance/fetcher/chef_server.rb +134 -0
  10. data/lib/chef/compliance/reporter/automate.rb +201 -0
  11. data/lib/chef/compliance/reporter/chef_server_automate.rb +94 -0
  12. data/lib/chef/compliance/reporter/compliance_enforcer.rb +20 -0
  13. data/lib/chef/compliance/reporter/json_file.rb +19 -0
  14. data/lib/chef/compliance/runner.rb +262 -0
  15. data/lib/chef/cookbook_manifest.rb +1 -0
  16. data/lib/chef/encrypted_data_bag_item/assertions.rb +1 -1
  17. data/lib/chef/exceptions.rb +4 -0
  18. data/lib/chef/http/ssl_policies.rb +33 -14
  19. data/lib/chef/knife/bootstrap/train_connector.rb +1 -1
  20. data/lib/chef/knife/core/formatting_options.rb +49 -0
  21. data/lib/chef/knife/core/node_presenter.rb +0 -25
  22. data/lib/chef/knife/core/status_presenter.rb +1 -26
  23. data/lib/chef/knife/core/ui.rb +4 -1
  24. data/lib/chef/knife/core/windows_bootstrap_context.rb +1 -1
  25. data/lib/chef/knife/node_show.rb +2 -1
  26. data/lib/chef/knife/search.rb +2 -1
  27. data/lib/chef/knife/ssh.rb +3 -1
  28. data/lib/chef/knife/status.rb +8 -11
  29. data/lib/chef/mixin/powershell_exec.rb +3 -1
  30. data/lib/chef/platform/query_helpers.rb +4 -4
  31. data/lib/chef/policy_builder/policyfile.rb +1 -1
  32. data/lib/chef/powershell.rb +2 -0
  33. data/lib/chef/provider/dsc_resource.rb +12 -24
  34. data/lib/chef/provider/dsc_script.rb +16 -20
  35. data/lib/chef/provider/git.rb +5 -5
  36. data/lib/chef/provider/package.rb +53 -19
  37. data/lib/chef/provider/package/dnf.rb +39 -12
  38. data/lib/chef/provider/package/dnf/dnf_helper.py +18 -5
  39. data/lib/chef/provider/package/dnf/python_helper.rb +6 -6
  40. data/lib/chef/provider/package/freebsd/pkgng.rb +3 -1
  41. data/lib/chef/provider/yum_repository.rb +2 -2
  42. data/lib/chef/resource/chef_client_config.rb +1 -1
  43. data/lib/chef/resource/chef_gem.rb +2 -2
  44. data/lib/chef/resource/cron/cron_d.rb +1 -0
  45. data/lib/chef/resource/dsc_script.rb +8 -1
  46. data/lib/chef/resource/file.rb +1 -1
  47. data/lib/chef/resource/gem_package.rb +2 -2
  48. data/lib/chef/resource/homebrew_cask.rb +3 -3
  49. data/lib/chef/resource/hostname.rb +3 -3
  50. data/lib/chef/resource/http_request.rb +1 -1
  51. data/lib/chef/resource/locale.rb +1 -1
  52. data/lib/chef/resource/mdadm.rb +2 -2
  53. data/lib/chef/resource/osx_profile.rb +7 -7
  54. data/lib/chef/resource/remote_directory.rb +1 -1
  55. data/lib/chef/resource/ruby.rb +1 -5
  56. data/lib/chef/resource/ruby_block.rb +1 -1
  57. data/lib/chef/resource/template.rb +2 -2
  58. data/lib/chef/resource/user/windows_user.rb +5 -0
  59. data/lib/chef/resource/windows_certificate.rb +9 -13
  60. data/lib/chef/resource/yum_repository.rb +5 -0
  61. data/lib/chef/resource_collection/resource_set.rb +1 -1
  62. data/lib/chef/util/dsc/configuration_generator.rb +52 -11
  63. data/lib/chef/util/dsc/lcm_output_parser.rb +3 -4
  64. data/lib/chef/util/dsc/local_configuration_manager.rb +17 -14
  65. data/lib/chef/util/dsc/resource_store.rb +5 -11
  66. data/lib/chef/version.rb +1 -1
  67. data/lib/chef/win32/api/file.rb +4 -0
  68. data/spec/data/rubygems.org/latest_specs.4.8.gz +0 -0
  69. data/spec/data/rubygems.org/nonexistent_gem +0 -0
  70. data/spec/data/rubygems.org/sexp_processor +0 -0
  71. data/spec/data/rubygems.org/sexp_processor-4.15.1.gemspec.rz +0 -0
  72. data/spec/data/ssl/binary/chef-rspec-der.cert +0 -0
  73. data/spec/data/ssl/binary/chef-rspec-der.key +0 -0
  74. data/spec/functional/resource/dnf_package_spec.rb +319 -16
  75. data/spec/functional/resource/dsc_script_spec.rb +3 -6
  76. data/spec/functional/resource/windows_certificate_spec.rb +204 -384
  77. data/spec/integration/client/client_spec.rb +2 -1
  78. data/spec/integration/compliance/compliance_spec.rb +81 -0
  79. data/spec/integration/recipes/recipe_dsl_spec.rb +1 -0
  80. data/spec/spec_helper.rb +1 -1
  81. data/spec/unit/client_spec.rb +1 -0
  82. data/spec/unit/compliance/fetcher/automate_spec.rb +134 -0
  83. data/spec/unit/compliance/fetcher/chef_server_spec.rb +93 -0
  84. data/spec/unit/compliance/reporter/automate_spec.rb +427 -0
  85. data/spec/unit/compliance/reporter/chef_server_automate_spec.rb +177 -0
  86. data/spec/unit/compliance/reporter/compliance_enforcer_spec.rb +48 -0
  87. data/spec/unit/compliance/runner_spec.rb +167 -0
  88. data/spec/unit/http/ssl_policies_spec.rb +107 -68
  89. data/spec/unit/knife/bootstrap_spec.rb +5 -17
  90. data/spec/unit/knife/core/node_editor_spec.rb +1 -1
  91. data/spec/unit/knife/core/status_presenter_spec.rb +54 -0
  92. data/spec/unit/mixin/openssl_helper_spec.rb +0 -7
  93. data/spec/unit/mixin/powershell_exec_spec.rb +1 -1
  94. data/spec/unit/platform/query_helpers_spec.rb +11 -12
  95. data/spec/unit/provider/dsc_resource_spec.rb +10 -27
  96. data/spec/unit/provider/dsc_script_spec.rb +1 -1
  97. data/spec/unit/provider/mount/windows_spec.rb +1 -0
  98. data/spec/unit/provider/package/freebsd/pkgng_spec.rb +1 -1
  99. data/spec/unit/provider/package/rubygems_spec.rb +39 -7
  100. data/spec/unit/provider/systemd_unit_spec.rb +1 -1
  101. data/spec/unit/resource/user/windows_user_spec.rb +36 -0
  102. data/spec/unit/resource/windows_certificate_spec.rb +12 -0
  103. data/spec/unit/util/dsc/configuration_generator_spec.rb +79 -0
  104. data/spec/unit/util/dsc/local_configuration_manager_spec.rb +27 -35
  105. metadata +55 -18
  106. data/lib/chef/util/powershell/cmdlet.rb +0 -169
  107. data/lib/chef/util/powershell/cmdlet_result.rb +0 -61
  108. data/spec/data/trusted_certs_empty/.gitkeep +0 -0
  109. data/spec/data/trusted_certs_empty/README.md +0 -1
  110. data/spec/functional/util/powershell/cmdlet_spec.rb +0 -111
  111. data/spec/scripts/ssl-serve.rb +0 -47
  112. data/spec/unit/util/powershell/cmdlet_spec.rb +0 -106
@@ -21,7 +21,7 @@ require "chef/mixin/powershell_exec"
21
21
  require "chef/mixin/windows_architecture_helper"
22
22
  require "support/shared/integration/integration_helper"
23
23
 
24
- describe Chef::Resource::DscScript, :windows_powershell_dsc_only do
24
+ describe Chef::Resource::DscScript, :windows_powershell_dsc_only, :ruby64_only do
25
25
  include Chef::Mixin::WindowsArchitectureHelper
26
26
  include Chef::Mixin::PowershellExec
27
27
  before(:all) do
@@ -261,12 +261,9 @@ describe Chef::Resource::DscScript, :windows_powershell_dsc_only do
261
261
 
262
262
  it "should raise an exception if the cwd is etc" do
263
263
  dsc_test_resource.cwd(dsc_environment_fail_etc_directory)
264
- expect { dsc_test_resource.run_action(:run) }.to raise_error(Chef::Exceptions::PowershellCmdletException)
265
- begin
264
+ expect {
266
265
  dsc_test_resource.run_action(:run)
267
- rescue Chef::Exceptions::PowershellCmdletException => e
268
- expect(e.message).to match(exception_message_signature)
269
- end
266
+ }.to raise_error(Chef::PowerShell::CommandFailed, /#{exception_message_signature}/)
270
267
  end
271
268
  end
272
269
  end
@@ -19,478 +19,298 @@ require "spec_helper"
19
19
  require "chef/mixin/powershell_exec"
20
20
  require "chef/resource/windows_certificate"
21
21
 
22
- module WindowsCertificateHelper
22
+ describe Chef::Resource::WindowsCertificate, :windows_only do
23
23
  include Chef::Mixin::PowershellExec
24
24
 
25
- def create_store(store)
26
- path = "Cert:\\LocalMachine\\" + store
27
- command = <<~EOC
28
- New-Item -Path #{path}
25
+ def create_store
26
+ powershell_exec <<~EOC
27
+ New-Item -Path Cert:\\LocalMachine\\#{store}
29
28
  EOC
30
- powershell_exec(command)
31
29
  end
32
30
 
33
- def cleanup(store)
34
- path = "Cert:\\LocalMachine\\" + store
35
- command = <<~EOC
36
- Remove-Item -Path #{path} -Recurse
31
+ def delete_store
32
+ powershell_exec <<~EOC
33
+ Remove-Item -Path Cert:\\LocalMachine\\#{store} -Recurse
37
34
  EOC
38
- powershell_exec(command)
39
35
  end
40
36
 
41
- def no_of_certificates
42
- path = "Cert:\\LocalMachine\\" + store
43
- # Seems weird that we have to call dir twice right?
44
- # The powershell pki module cache the last dir in module session state
45
- # Issuing dir with a different arg (-Force) seems to refresh that state.
46
- command = <<~EOC
47
- dir #{path} -Force | Out-Null
48
- (dir #{path} | measure).Count
37
+ def certificate_count
38
+ powershell_exec(<<~EOC).result.to_i
39
+ (Get-ChildItem -Force -Path Cert:\\LocalMachine\\#{store} | measure).Count
49
40
  EOC
50
- powershell_exec(command).result.to_i
51
41
  end
52
- end
53
42
 
54
- describe Chef::Resource::WindowsCertificate, :windows_only do
55
- include WindowsCertificateHelper
56
-
57
- let(:stdout) { StringIO.new }
58
- let(:username) { "ChefFunctionalTest" }
59
- let(:node) { Chef::Node.new }
60
- let(:events) { Chef::EventDispatch::Dispatcher.new }
61
- let(:run_context) { Chef::RunContext.new(node, {}, events) }
62
- let(:new_resource) { Chef::Resource::WindowsCertificate.new(username, run_context) }
63
43
  let(:password) { "P@ssw0rd!" }
64
44
  let(:store) { "Chef-Functional-Test" }
65
- let(:certificate_path) { File.expand_path(File.join(CHEF_SPEC_DATA, "windows_certificates")) }
66
- let(:cer_path) { File.join(certificate_path, "test.cer") }
67
- let(:base64_path) { File.join(certificate_path, "base64_test.cer") }
68
- let(:pem_path) { File.join(certificate_path, "test.pem") }
69
- let(:p7b_path) { File.join(certificate_path, "test.p7b") }
70
- let(:pfx_path) { File.join(certificate_path, "test.pfx") }
71
- let(:out_path) { File.join(certificate_path, "testout.pem") }
45
+ let(:cer_path) { File.join(CHEF_SPEC_DATA, "windows_certificates", "test.cer") }
46
+ let(:base64_path) { File.join(CHEF_SPEC_DATA, "windows_certificates", "base64_test.cer") }
47
+ let(:pem_path) { File.join(CHEF_SPEC_DATA, "windows_certificates", "test.pem") }
48
+ let(:p7b_path) { File.join(CHEF_SPEC_DATA, "windows_certificates", "test.p7b") }
49
+ let(:pfx_path) { File.join(CHEF_SPEC_DATA, "windows_certificates", "test.pfx") }
72
50
  let(:tests_thumbprint) { "e45a4a7ff731e143cf20b8bfb9c7c4edd5238bb3" }
73
- let(:other_cer_path) { File.join(certificate_path, "othertest.cer") }
51
+ let(:other_cer_path) { File.join(CHEF_SPEC_DATA, "windows_certificates", "othertest.cer") }
74
52
  let(:others_thumbprint) { "6eae1deefaf59daf1a97c9ceeff39c98b3da38cb" }
75
53
  let(:p7b_thumbprint) { "f867e25b928061318ed2c36ca517681774b06260" }
76
54
  let(:p7b_nested_thumbprint) { "dc395eae6be5b69951b8b6e1090cfc33df30d2cd" }
77
55
 
56
+ let(:resource) do
57
+ run_context = Chef::RunContext.new(Chef::Node.new, {}, Chef::EventDispatch::Dispatcher.new)
58
+ Chef::Resource::WindowsCertificate.new("ChefFunctionalTest", run_context).tap do |r|
59
+ r.store_name = store
60
+ end
61
+ end
62
+
78
63
  before do
79
- opts = { store_name: store }
80
- key = :store_name
81
- to_be = ["TRUSTEDPUBLISHER", "TrustedPublisher", "CLIENTAUTHISSUER",
82
- "REMOTE DESKTOP", "ROOT", "TRUSTEDDEVICES", "WEBHOSTING",
83
- "CA", "AUTHROOT", "TRUSTEDPEOPLE", "MY", "SMARTCARDROOT", "TRUST",
84
- "DISALLOWED"]
85
-
86
- # Byepassing the validation so that we may create a custom store
64
+ # Bypass validation of the store name so we can use a fake test store.
87
65
  allow_any_instance_of(Chef::Mixin::ParamsValidate)
88
66
  .to receive(:_pv_equal_to)
89
- .with(opts, key, to_be)
67
+ .with({ store_name: store }, :store_name, anything)
90
68
  .and_return(true)
91
69
 
92
- # Creating a custom store for the testing
93
- create_store(store)
70
+ create_store
71
+ end
72
+
73
+ after { delete_store }
94
74
 
95
- allow(Chef::Log).to receive(:info) do |msg|
96
- stdout.puts(msg)
75
+ describe "action: create" do
76
+ it "starts with no certificates" do
77
+ expect(certificate_count).to eq(0)
97
78
  end
98
- end
99
79
 
100
- after { cleanup(store) }
80
+ it "can add a certificate idempotently" do
81
+ resource.source = cer_path
82
+ resource.run_action(:create)
101
83
 
102
- subject(:win_certificate) do
103
- new_resource.store_name = store
104
- new_resource
105
- end
84
+ expect(certificate_count).to eq(1)
85
+ expect(resource).to be_updated_by_last_action
106
86
 
107
- it "Initially there are no certificates" do
108
- expect(no_of_certificates).to eq(0)
109
- end
87
+ # Adding the cert again should have no effect
88
+ resource.run_action(:create)
89
+ expect(certificate_count).to eq(1)
90
+ expect(resource).not_to be_updated_by_last_action
110
91
 
111
- describe "action :create" do
112
- before do
113
- win_certificate.source = cer_path
114
- win_certificate.run_action(:create)
115
- end
92
+ # Adding the cert again with a different format should have no effect
93
+ resource.source = pem_path
94
+ resource.run_action(:create)
95
+ expect(certificate_count).to eq(1)
96
+ expect(resource).not_to be_updated_by_last_action
116
97
 
117
- context "Adding a certificate" do
118
- it "Imports certificate into store" do
119
- expect(no_of_certificates).to eq(1)
120
- end
98
+ # Adding another cert should work correctly
99
+ resource.source = other_cer_path
100
+ resource.run_action(:create)
121
101
 
122
- it "Converges while addition" do
123
- expect(win_certificate).to be_updated_by_last_action
124
- end
102
+ expect(certificate_count).to eq(2)
103
+ expect(resource).to be_updated_by_last_action
125
104
  end
126
105
 
127
- context "Again adding the same certificate" do
128
- before do
129
- win_certificate.run_action(:create)
130
- end
131
- it "Does not imports certificate into store" do
132
- expect(no_of_certificates).to eq(1)
133
- end
134
- it "Idempotent: Does not converge while addition" do
135
- expect(no_of_certificates).to eq(1)
136
- expect(win_certificate).not_to be_updated_by_last_action
137
- end
138
- end
106
+ it "can add a base64 encoded certificate idempotently" do
107
+ resource.source = base64_path
108
+ resource.run_action(:create)
139
109
 
140
- context "Again adding the same certificate of other format" do
141
- before do
142
- win_certificate.source = pem_path
143
- win_certificate.run_action(:create)
144
- end
145
- it "Does not imports certificate into store" do
146
- expect(no_of_certificates).to eq(1)
147
- end
148
- it "Idempotent: Does not converge while addition" do
149
- expect(no_of_certificates).to eq(1)
150
- expect(win_certificate).not_to be_updated_by_last_action
151
- end
152
- end
110
+ expect(certificate_count).to eq(1)
153
111
 
154
- context "Adding another certificate" do
155
- before do
156
- win_certificate.source = other_cer_path
157
- win_certificate.run_action(:create)
158
- end
159
- it "Imports certificate into store" do
160
- expect(no_of_certificates).to eq(2)
161
- end
162
- it "Converges while addition" do
163
- expect(no_of_certificates).to eq(2)
164
- expect(win_certificate).to be_updated_by_last_action
165
- end
112
+ resource.run_action(:create)
113
+ expect(certificate_count).to eq(1)
114
+ expect(resource).not_to be_updated_by_last_action
166
115
  end
167
- end
168
116
 
169
- describe "Works for various formats" do
170
- context "Adds CER" do
171
- before do
172
- win_certificate.source = cer_path
173
- win_certificate.run_action(:create)
174
- end
175
- it "Imports certificate into store" do
176
- expect(no_of_certificates).to eq(1)
177
- end
178
- it "Idempotent: Does not converge while adding again" do
179
- win_certificate.run_action(:create)
180
- expect(no_of_certificates).to eq(1)
181
- expect(win_certificate).not_to be_updated_by_last_action
182
- end
183
- end
117
+ it "can add a PEM certificate idempotently" do
118
+ resource.source = pem_path
119
+ resource.run_action(:create)
184
120
 
185
- context "Adds Base64 Encoded CER" do
186
- before do
187
- win_certificate.source = base64_path
188
- win_certificate.run_action(:create)
189
- end
190
- it "Imports certificate into store" do
191
- expect(no_of_certificates).to eq(1)
192
- end
193
- it "Idempotent: Does not converge while adding again" do
194
- win_certificate.run_action(:create)
195
- expect(no_of_certificates).to eq(1)
196
- expect(win_certificate).not_to be_updated_by_last_action
197
- end
121
+ expect(certificate_count).to eq(1)
122
+
123
+ resource.run_action(:create)
124
+
125
+ expect(certificate_count).to eq(1)
126
+ expect(resource).not_to be_updated_by_last_action
198
127
  end
199
128
 
200
- context "Adds PEM" do
201
- before do
202
- win_certificate.source = pem_path
203
- win_certificate.run_action(:create)
204
- end
205
- it "Imports certificate into store" do
206
- expect(no_of_certificates).to eq(1)
207
- end
208
- it "Idempotent: Does not converge while adding again" do
209
- win_certificate.run_action(:create)
210
- expect(no_of_certificates).to eq(1)
211
- expect(win_certificate).not_to be_updated_by_last_action
212
- end
129
+ it "can add a P7B certificate idempotently" do
130
+ resource.source = p7b_path
131
+ resource.run_action(:create)
132
+
133
+ # A P7B cert includes nested certs
134
+ expect(certificate_count).to eq(3)
135
+
136
+ resource.run_action(:create)
137
+
138
+ expect(resource).not_to be_updated_by_last_action
139
+ expect(certificate_count).to eq(3)
213
140
  end
214
141
 
215
- context "Adds P7B" do
216
- before do
217
- win_certificate.source = p7b_path
218
- win_certificate.run_action(:create)
219
- end
220
- it "Imports certificate into store" do
221
- expect(no_of_certificates).not_to eq(0)
222
- end
223
- it "Idempotent: Does not converge while adding again" do
224
- win_certificate.run_action(:create)
225
- expect(win_certificate).not_to be_updated_by_last_action
226
- end
227
- it "Nested certificates are also imported" do
228
- expect(no_of_certificates).to eq(3)
229
- end
142
+ it "can add a PFX certificate idempotently with a valid password" do
143
+ resource.source = pfx_path
144
+ resource.pfx_password = password
145
+ resource.run_action(:create)
146
+
147
+ expect(certificate_count).to eq(1)
148
+
149
+ resource.run_action(:create)
150
+ expect(certificate_count).to eq(1)
151
+ expect(resource).not_to be_updated_by_last_action
230
152
  end
231
153
 
232
- context "Adds PFX" do
233
- context "With valid password" do
234
- before do
235
- win_certificate.source = pfx_path
236
- win_certificate.pfx_password = password
237
- win_certificate.run_action(:create)
238
- end
239
- it "Imports certificate into store" do
240
- expect(no_of_certificates).to eq(1)
241
- end
242
- it "Idempotent: Does not converge while adding again" do
243
- win_certificate.run_action(:create)
244
- expect(no_of_certificates).to eq(1)
245
- expect(win_certificate).not_to be_updated_by_last_action
246
- end
247
- end
154
+ it "raises an error when adding a PFX certificate with an invalid password" do
155
+ resource.source = pfx_path
156
+ resource.pfx_password = "Invalid password"
248
157
 
249
- context "With Invalid password" do
250
- before do
251
- win_certificate.source = pfx_path
252
- win_certificate.pfx_password = "Invalid password"
253
- end
254
- it "Raises an error" do
255
- expect { win_certificate.run_action(:create) }.to raise_error(OpenSSL::PKCS12::PKCS12Error)
256
- end
257
- end
158
+ expect { resource.run_action(:create) }.to raise_error(OpenSSL::PKCS12::PKCS12Error)
258
159
  end
259
160
  end
260
161
 
261
162
  describe "action: verify" do
262
- context "When a certificate is not present" do
263
- before do
264
- win_certificate.source = tests_thumbprint
265
- win_certificate.run_action(:verify)
266
- end
267
- it "Initial check if certificate is not present" do
268
- expect(no_of_certificates).to eq(0)
269
- end
270
- it "Displays correct message" do
271
- expect(stdout.string.strip).to eq("Certificate not found")
272
- end
273
- it "Does not converge while verifying" do
274
- expect(win_certificate).not_to be_updated_by_last_action
275
- end
163
+ it "fails with no certificates in the store" do
164
+ expect(Chef::Log).to receive(:info).with("Certificate not found")
165
+
166
+ resource.source = tests_thumbprint
167
+ resource.run_action(:verify)
168
+
169
+ expect(resource).not_to be_updated_by_last_action
276
170
  end
277
171
 
278
- context "When a certificate is present" do
172
+ context "with a certificate in the store" do
279
173
  before do
280
- win_certificate.source = cer_path
281
- win_certificate.run_action(:create)
174
+ resource.source = cer_path
175
+ resource.run_action(:create)
282
176
  end
283
177
 
284
- context "For a valid thumbprint" do
285
- before do
286
- win_certificate.source = tests_thumbprint
287
- win_certificate.run_action(:verify)
288
- end
289
- it "Initial check if certificate is present" do
290
- expect(no_of_certificates).to eq(1)
291
- end
292
- it "Displays correct message" do
293
- expect(stdout.string.strip).to eq("Certificate is valid")
294
- end
295
- it "Does not converge while verifying" do
296
- expect(win_certificate).not_to be_updated_by_last_action
297
- end
178
+ it "succeeds with a valid thumbprint" do
179
+ expect(Chef::Log).to receive(:info).with("Certificate is valid")
180
+
181
+ resource.source = tests_thumbprint
182
+ resource.run_action(:verify)
183
+
184
+ expect(resource).not_to be_updated_by_last_action
298
185
  end
299
186
 
300
- context "For an invalid thumbprint" do
301
- before do
302
- win_certificate.source = others_thumbprint
303
- win_certificate.run_action(:verify)
304
- end
305
- it "Initial check if certificate is present" do
306
- expect(no_of_certificates).to eq(1)
307
- end
308
- it "Displays correct message" do
309
- expect(stdout.string.strip).to eq("Certificate not found")
310
- end
311
- it "Does not converge while verifying" do
312
- expect(win_certificate).not_to be_updated_by_last_action
313
- end
187
+ it "fails with an invalid thumbprint" do
188
+ expect(Chef::Log).to receive(:info).with("Certificate not found")
189
+
190
+ resource.source = others_thumbprint
191
+ resource.run_action(:verify)
192
+
193
+ expect(resource).not_to be_updated_by_last_action
314
194
  end
315
195
  end
316
196
 
317
- context "When multiple certificates are present" do
197
+ context "with a nested certificate in the store" do
318
198
  before do
319
- win_certificate.source = p7b_path
320
- win_certificate.run_action(:create)
199
+ resource.source = p7b_path
200
+ resource.run_action(:create)
321
201
  end
322
202
 
323
- context "With main certificate's thumbprint" do
324
- before do
325
- win_certificate.source = p7b_thumbprint
326
- win_certificate.run_action(:verify)
327
- end
328
- it "Initial check if certificate is present" do
329
- expect(no_of_certificates).to eq(3)
330
- end
331
- it "Displays correct message" do
332
- expect(stdout.string.strip).to eq("Certificate is valid")
333
- end
334
- it "Does not converge while verifying" do
335
- expect(win_certificate).not_to be_updated_by_last_action
336
- end
203
+ it "succeeds with the main certificate's thumbprint" do
204
+ expect(Chef::Log).to receive(:info).with("Certificate is valid")
205
+
206
+ resource.source = p7b_thumbprint
207
+ resource.run_action(:verify)
208
+
209
+ expect(resource).not_to be_updated_by_last_action
337
210
  end
338
211
 
339
- context "With nested certificate's thumbprint" do
340
- before do
341
- win_certificate.source = p7b_nested_thumbprint
342
- win_certificate.run_action(:verify)
343
- end
344
- it "Initial check if certificate is present" do
345
- expect(no_of_certificates).to eq(3)
346
- end
347
- it "Displays correct message" do
348
- expect(stdout.string.strip).to eq("Certificate is valid")
349
- end
350
- it "Does not converge while verifying" do
351
- expect(win_certificate).not_to be_updated_by_last_action
352
- end
212
+ it "succeeds with the nested certificate's thumbprint" do
213
+ expect(Chef::Log).to receive(:info).with("Certificate is valid")
214
+
215
+ resource.source = p7b_nested_thumbprint
216
+ resource.run_action(:verify)
217
+
218
+ expect(resource).not_to be_updated_by_last_action
353
219
  end
354
220
 
355
- context "For an invalid thumbprint" do
356
- before do
357
- win_certificate.source = others_thumbprint
358
- win_certificate.run_action(:verify)
359
- end
360
- it "Initial check if certificate is present" do
361
- expect(no_of_certificates).to eq(3)
362
- end
363
- it "Displays correct message" do
364
- expect(stdout.string.strip).to eq("Certificate not found")
365
- end
366
- it "Does not converge while verifying" do
367
- expect(win_certificate).not_to be_updated_by_last_action
368
- end
221
+ it "fails with an invalid thumbprint" do
222
+ expect(Chef::Log).to receive(:info).with("Certificate not found")
223
+
224
+ resource.source = others_thumbprint
225
+ resource.run_action(:verify)
226
+
227
+ expect(resource).not_to be_updated_by_last_action
369
228
  end
370
229
  end
371
230
  end
372
231
 
373
232
  describe "action: fetch" do
374
- context "When a certificate is not present" do
375
- before do
376
- win_certificate.source = tests_thumbprint
377
- win_certificate.run_action(:fetch)
378
- end
379
- it "Initial check if certificate is not present" do
380
- expect(no_of_certificates).to eq(0)
381
- end
382
- it "Does not show any content" do
383
- expect(stdout.string.strip).to be_empty
384
- end
385
- it "Does not converge while fetching" do
386
- expect(win_certificate).not_to be_updated_by_last_action
387
- end
233
+ it "does nothing with no certificates in the store" do
234
+ expect(Chef::Log).not_to receive(:info)
235
+
236
+ resource.source = tests_thumbprint
237
+ resource.run_action(:fetch)
238
+
239
+ expect(resource).not_to be_updated_by_last_action
388
240
  end
389
241
 
390
- context "When a certificate is present" do
242
+ context "with a certificate in the store" do
391
243
  before do
392
- win_certificate.source = cer_path
393
- win_certificate.run_action(:create)
244
+ resource.source = cer_path
245
+ resource.run_action(:create)
394
246
  end
395
247
 
396
- after do
397
- if File.exist?(out_path)
398
- File.delete(out_path)
399
- end
400
- end
248
+ it "succeeds with a valid thumbprint" do
249
+ resource.source = tests_thumbprint
401
250
 
402
- context "For a valid thumbprint" do
403
- before do
404
- win_certificate.source = tests_thumbprint
405
- win_certificate.cert_path = out_path
406
- win_certificate.run_action(:fetch)
407
- end
408
- it "Initial check if certificate is present" do
409
- expect(no_of_certificates).to eq(1)
410
- end
411
- it "Stores Certificate content at given path" do
412
- expect(File.exist?(out_path)).to be_truthy
413
- end
414
- it "Does not converge while fetching" do
415
- expect(win_certificate).not_to be_updated_by_last_action
251
+ Dir.mktmpdir do |dir|
252
+ path = File.join(dir, "test.pem")
253
+ expect(Chef::Log).to receive(:info).with("Certificate export in #{path}")
254
+
255
+ resource.cert_path = path
256
+ resource.run_action(:fetch)
257
+
258
+ expect(File.exist?(path)).to be_truthy
416
259
  end
260
+
261
+ expect(resource).not_to be_updated_by_last_action
417
262
  end
418
263
 
419
- context "For an invalid thumbprint" do
420
- before do
421
- win_certificate.source = others_thumbprint
422
- win_certificate.cert_path = out_path
423
- win_certificate.run_action(:fetch)
424
- end
425
- it "Initial check if certificate is present" do
426
- expect(no_of_certificates).to eq(1)
427
- end
428
- it "Does not show any content" do
429
- expect(stdout.string.strip).to be_empty
430
- end
431
- it "Does not store certificate content at given path" do
432
- expect(File.exist?(out_path)).to be_falsy
433
- end
434
- it "Does not converge while fetching" do
435
- expect(win_certificate).not_to be_updated_by_last_action
264
+ it "fails with an invalid thumbprint" do
265
+ expect(Chef::Log).not_to receive(:info)
266
+
267
+ resource.source = others_thumbprint
268
+
269
+ Dir.mktmpdir do |dir|
270
+ path = File.join(dir, "test.pem")
271
+
272
+ resource.cert_path = path
273
+ resource.run_action(:fetch)
274
+
275
+ expect(File.exist?(path)).to be_falsy
436
276
  end
277
+
278
+ expect(resource).not_to be_updated_by_last_action
437
279
  end
438
280
  end
439
281
  end
440
282
 
441
283
  describe "action: delete" do
442
- context "When a certificate is not present" do
443
- before do
444
- win_certificate.source = tests_thumbprint
445
- win_certificate.run_action(:delete)
446
- end
447
- it "Initial check if certificate is not present" do
448
- expect(no_of_certificates).to eq(0)
449
- end
450
- it "Does not delete any certificate" do
451
- expect(stdout.string.strip).to be_empty
452
- end
284
+ it "does nothing when attempting to delete a certificate that doesn't exist" do
285
+ expect(Chef::Log).to receive(:debug).with("Certificate not found")
286
+
287
+ resource.source = tests_thumbprint
288
+ resource.run_action(:delete)
453
289
  end
454
290
 
455
- context "When a certificate is present" do
456
- before do
457
- win_certificate.source = cer_path
458
- win_certificate.run_action(:create)
459
- end
460
- before { win_certificate.source = tests_thumbprint }
461
- it "Initial check if certificate is present" do
462
- expect(no_of_certificates).to eq(1)
463
- end
464
- it "Deletes the certificate" do
465
- win_certificate.run_action(:delete)
466
- expect(no_of_certificates).to eq(0)
467
- end
468
- it "Converges while deleting" do
469
- win_certificate.run_action(:delete)
470
- expect(win_certificate).to be_updated_by_last_action
471
- end
472
- it "Idempotent: Does not converge while deleting again" do
473
- win_certificate.run_action(:delete)
474
- win_certificate.run_action(:delete)
475
- expect(no_of_certificates).to eq(0)
476
- expect(win_certificate).not_to be_updated_by_last_action
477
- end
478
- it "Deletes the valid certificate" do
479
- # Add another certificate"
480
- win_certificate.source = other_cer_path
481
- win_certificate.run_action(:create)
482
- expect(no_of_certificates).to eq(2)
483
-
484
- # Delete previously added certificate
485
- win_certificate.source = tests_thumbprint
486
- win_certificate.run_action(:delete)
487
- expect(no_of_certificates).to eq(1)
488
-
489
- # Verify another certificate still exists
490
- win_certificate.source = others_thumbprint
491
- win_certificate.run_action(:verify)
492
- expect(stdout.string.strip).to eq("Certificate is valid")
493
- end
291
+ it "deletes an existing certificate while leaving other certificates alone" do
292
+ # Add two certs
293
+ resource.source = cer_path
294
+ resource.run_action(:create)
295
+
296
+ resource.source = other_cer_path
297
+ resource.run_action(:create)
298
+
299
+ # Delete the first cert added
300
+ resource.source = tests_thumbprint
301
+ resource.run_action(:delete)
302
+
303
+ expect(certificate_count).to eq(1)
304
+ expect(resource).to be_updated_by_last_action
305
+
306
+ resource.run_action(:delete)
307
+ expect(certificate_count).to eq(1)
308
+ expect(resource).not_to be_updated_by_last_action
309
+
310
+ # Verify second cert still exists
311
+ expect(Chef::Log).to receive(:info).with("Certificate is valid")
312
+ resource.source = others_thumbprint
313
+ resource.run_action(:verify)
494
314
  end
495
315
  end
496
316
  end