chef 16.9.20-universal-mingw32 → 16.11.7-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.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/chef-universal-mingw32.gemspec +1 -1
- data/chef.gemspec +11 -2
- data/lib/chef/compliance/default_attributes.rb +6 -2
- data/lib/chef/compliance/fetcher/automate.rb +15 -4
- data/lib/chef/compliance/runner.rb +11 -4
- data/lib/chef/dsl/reboot_pending.rb +1 -1
- data/lib/chef/file_access_control/windows.rb +4 -4
- data/lib/chef/file_cache.rb +4 -4
- data/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb +1 -1
- data/lib/chef/handler/json_file.rb +1 -1
- data/lib/chef/knife/bootstrap.rb +54 -4
- data/lib/chef/provider/mount/mount.rb +1 -1
- data/lib/chef/provider/package.rb +2 -2
- data/lib/chef/provider/package/dnf/dnf_helper.py +5 -1
- data/lib/chef/provider/package/yum/yum_helper.py +4 -0
- data/lib/chef/resource.rb +27 -3
- data/lib/chef/resource/chef_client_cron.rb +1 -1
- data/lib/chef/resource/windows_certificate.rb +47 -17
- data/lib/chef/resource_inspector.rb +5 -1
- data/lib/chef/shell.rb +32 -1
- data/lib/chef/util/dsc/configuration_generator.rb +1 -1
- data/lib/chef/version.rb +1 -1
- data/lib/chef/version_string.rb +1 -1
- data/spec/functional/resource/ohai_spec.rb +2 -10
- data/spec/integration/compliance/compliance_spec.rb +2 -1
- data/spec/integration/recipes/resource_action_spec.rb +14 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/compliance/fetcher/automate_spec.rb +8 -0
- data/spec/unit/compliance/runner_spec.rb +57 -9
- data/spec/unit/dsl/reboot_pending_spec.rb +2 -2
- data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +2 -2
- data/spec/unit/knife/bootstrap_spec.rb +42 -3
- data/spec/unit/knife/supermarket_share_spec.rb +5 -6
- data/spec/unit/provider/mount/mount_spec.rb +1 -0
- data/spec/unit/provider/package/dnf/python_helper_spec.rb +7 -1
- data/spec/unit/resource/chef_client_cron_spec.rb +8 -8
- data/spec/unit/resource_inspector_spec.rb +7 -2
- data/spec/unit/resource_spec.rb +46 -0
- metadata +20 -14
@@ -213,7 +213,7 @@ class Chef
|
|
213
213
|
#
|
214
214
|
def log_command
|
215
215
|
if new_resource.append_log_file
|
216
|
-
"
|
216
|
+
">> #{::File.join(new_resource.log_directory, new_resource.log_file_name)} 2>&1"
|
217
217
|
else
|
218
218
|
"> #{::File.join(new_resource.log_directory, new_resource.log_file_name)} 2>&1"
|
219
219
|
end
|
@@ -76,7 +76,7 @@ class Chef
|
|
76
76
|
default: "MY", equal_to: ["TRUSTEDPUBLISHER", "TrustedPublisher", "CLIENTAUTHISSUER", "REMOTE DESKTOP", "ROOT", "TRUSTEDDEVICES", "WEBHOSTING", "CA", "AUTHROOT", "TRUSTEDPEOPLE", "MY", "SMARTCARDROOT", "TRUST", "DISALLOWED"]
|
77
77
|
|
78
78
|
property :user_store, [TrueClass, FalseClass],
|
79
|
-
description: "Use the
|
79
|
+
description: "Use the `CurrentUser` store instead of the default `LocalMachine` store. Note: Prior to #{ChefUtils::Dist::Infra::CLIENT}. 16.10 this property was ignored.",
|
80
80
|
default: false
|
81
81
|
|
82
82
|
property :cert_path, String,
|
@@ -119,7 +119,7 @@ class Chef
|
|
119
119
|
code_script << acl_script(hash)
|
120
120
|
guard_script << cert_exists_script(hash)
|
121
121
|
|
122
|
-
powershell_script "setting the acls on #{new_resource.source} in #{
|
122
|
+
powershell_script "setting the acls on #{new_resource.source} in #{ps_cert_location}\\#{new_resource.store_name}" do
|
123
123
|
convert_boolean_return true
|
124
124
|
code code_script
|
125
125
|
only_if guard_script
|
@@ -161,25 +161,47 @@ class Chef
|
|
161
161
|
end
|
162
162
|
|
163
163
|
action_class do
|
164
|
+
|
165
|
+
CERT_SYSTEM_STORE_LOCAL_MACHINE = 0x00020000
|
166
|
+
CERT_SYSTEM_STORE_CURRENT_USER = 0x00010000
|
167
|
+
|
164
168
|
def add_cert(cert_obj)
|
165
|
-
store = ::Win32::Certstore.open(new_resource.store_name)
|
169
|
+
store = ::Win32::Certstore.open(new_resource.store_name, store_location: native_cert_location)
|
166
170
|
store.add(cert_obj)
|
167
171
|
end
|
168
172
|
|
169
173
|
def add_pfx_cert
|
170
174
|
exportable = new_resource.exportable ? 1 : 0
|
171
|
-
store = ::Win32::Certstore.open(new_resource.store_name)
|
175
|
+
store = ::Win32::Certstore.open(new_resource.store_name, store_location: native_cert_location)
|
172
176
|
store.add_pfx(new_resource.source, new_resource.pfx_password, exportable)
|
173
177
|
end
|
174
178
|
|
175
179
|
def delete_cert
|
176
|
-
store = ::Win32::Certstore.open(new_resource.store_name)
|
177
|
-
store.delete(new_resource.source)
|
180
|
+
store = ::Win32::Certstore.open(new_resource.store_name, store_location: native_cert_location)
|
181
|
+
store.delete(resolve_thumbprint(new_resource.source))
|
178
182
|
end
|
179
183
|
|
180
184
|
def fetch_cert
|
181
|
-
store = ::Win32::Certstore.open(new_resource.store_name)
|
182
|
-
store.get(new_resource.source)
|
185
|
+
store = ::Win32::Certstore.open(new_resource.store_name, store_location: native_cert_location)
|
186
|
+
store.get(resolve_thumbprint(new_resource.source))
|
187
|
+
end
|
188
|
+
|
189
|
+
# Thumbprints should be exactly 40 Hex characters
|
190
|
+
def valid_thumbprint?(string)
|
191
|
+
string.scan(/\H/).empty? && string.length == 40
|
192
|
+
end
|
193
|
+
|
194
|
+
def get_thumbprint(store_name, location, source)
|
195
|
+
<<-GETTHUMBPRINTCODE
|
196
|
+
$content = Get-ChildItem -Path Cert:\\#{location}\\#{store_name} | Where-Object {$_.Subject -Match "#{source}"} | Select-Object Thumbprint
|
197
|
+
$content.thumbprint
|
198
|
+
GETTHUMBPRINTCODE
|
199
|
+
end
|
200
|
+
|
201
|
+
def resolve_thumbprint(thumbprint)
|
202
|
+
return thumbprint if valid_thumbprint?(thumbprint)
|
203
|
+
|
204
|
+
powershell_exec!(get_thumbprint(new_resource.store_name, ps_cert_location, new_resource.source)).result
|
183
205
|
end
|
184
206
|
|
185
207
|
# Checks whether a certificate with the given thumbprint
|
@@ -187,9 +209,11 @@ class Chef
|
|
187
209
|
# If the certificate is not present, verify_cert returns a String: "Certificate not found"
|
188
210
|
# But if it is present but expired, it returns a Boolean: false
|
189
211
|
# Otherwise, it returns a Boolean: true
|
212
|
+
# updated this method to accept either a subject name or a thumbprint - 1/29/2021
|
213
|
+
|
190
214
|
def verify_cert(thumbprint = new_resource.source)
|
191
|
-
store = ::Win32::Certstore.open(new_resource.store_name)
|
192
|
-
store.valid?(thumbprint)
|
215
|
+
store = ::Win32::Certstore.open(new_resource.store_name, store_location: native_cert_location)
|
216
|
+
store.valid?(resolve_thumbprint(thumbprint))
|
193
217
|
end
|
194
218
|
|
195
219
|
def show_or_store_cert(cert_obj)
|
@@ -230,13 +254,19 @@ class Chef
|
|
230
254
|
out_file.close
|
231
255
|
end
|
232
256
|
|
233
|
-
|
234
|
-
|
257
|
+
# this array structure is solving 2 problems. The first is that we need to have support for both the CurrentUser AND LocalMachine stores
|
258
|
+
# Secondly, we need to pass the proper constant name for each store to win32-certstore but also pass the short name to powershell scripts used here
|
259
|
+
def ps_cert_location
|
260
|
+
new_resource.user_store ? "CurrentUser" : "LocalMachine"
|
261
|
+
end
|
262
|
+
|
263
|
+
def native_cert_location
|
264
|
+
new_resource.user_store ? CERT_SYSTEM_STORE_CURRENT_USER : CERT_SYSTEM_STORE_LOCAL_MACHINE
|
235
265
|
end
|
236
266
|
|
237
267
|
def cert_script(persist)
|
238
268
|
cert_script = "$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2"
|
239
|
-
file = Chef::Util::PathHelper.cleanpath(new_resource.source)
|
269
|
+
file = Chef::Util::PathHelper.cleanpath(new_resource.source, ps_cert_location)
|
240
270
|
cert_script << " \"#{file}\""
|
241
271
|
if ::File.extname(file.downcase) == ".pfx"
|
242
272
|
cert_script << ", \"#{new_resource.pfx_password}\""
|
@@ -252,14 +282,14 @@ class Chef
|
|
252
282
|
def cert_exists_script(hash)
|
253
283
|
<<-EOH
|
254
284
|
$hash = #{hash}
|
255
|
-
Test-Path "Cert:\\#{
|
285
|
+
Test-Path "Cert:\\#{ps_cert_location}\\#{new_resource.store_name}\\$hash"
|
256
286
|
EOH
|
257
287
|
end
|
258
288
|
|
259
289
|
def within_store_script
|
260
290
|
inner_script = yield "$store"
|
261
291
|
<<-EOH
|
262
|
-
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "#{new_resource.store_name}", ([System.Security.Cryptography.X509Certificates.StoreLocation]::#{
|
292
|
+
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "#{new_resource.store_name}", ([System.Security.Cryptography.X509Certificates.StoreLocation]::#{ps_cert_location})
|
263
293
|
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
|
264
294
|
#{inner_script}
|
265
295
|
$store.Close()
|
@@ -273,7 +303,7 @@ class Chef
|
|
273
303
|
# and from https://msdn.microsoft.com/en-us/library/windows/desktop/bb204778(v=vs.85).aspx
|
274
304
|
set_acl_script = <<-EOH
|
275
305
|
$hash = #{hash}
|
276
|
-
$storeCert = Get-ChildItem "cert:\\#{
|
306
|
+
$storeCert = Get-ChildItem "cert:\\#{ps_cert_location}\\#{new_resource.store_name}\\$hash"
|
277
307
|
if ($storeCert -eq $null) { throw 'no key exists.' }
|
278
308
|
$keyname = $storeCert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
|
279
309
|
if ($keyname -eq $null) { throw 'no private key exists.' }
|
@@ -340,7 +370,7 @@ class Chef
|
|
340
370
|
if verify_cert(thumbprint) == true
|
341
371
|
Chef::Log.debug("Certificate is already present")
|
342
372
|
else
|
343
|
-
converge_by("Adding certificate #{new_resource.source} into Store #{new_resource.store_name}") do
|
373
|
+
converge_by("Adding certificate #{new_resource.source} into #{ps_cert_location} Store #{new_resource.store_name}") do
|
344
374
|
if is_pfx
|
345
375
|
add_pfx_cert
|
346
376
|
else
|
@@ -41,7 +41,11 @@ class Chef
|
|
41
41
|
data[:description] = resource.description
|
42
42
|
# data[:deprecated] = resource.deprecated || false
|
43
43
|
data[:default_action] = resource.default_action
|
44
|
-
data[:actions] =
|
44
|
+
data[:actions] = {}
|
45
|
+
resource.allowed_actions.each do |action|
|
46
|
+
data[:actions][action] = resource.action_description(action)
|
47
|
+
end
|
48
|
+
|
45
49
|
data[:examples] = resource.examples
|
46
50
|
data[:introduced] = resource.introduced
|
47
51
|
data[:preview] = resource.preview_resource
|
data/lib/chef/shell.rb
CHANGED
@@ -25,6 +25,7 @@ require "pp" unless defined?(PP)
|
|
25
25
|
require "etc" unless defined?(Etc)
|
26
26
|
require "mixlib/cli" unless defined?(Mixlib::CLI)
|
27
27
|
require "chef-utils/dist" unless defined?(ChefUtils::Dist)
|
28
|
+
require "chef-config/mixin/dot_d"
|
28
29
|
|
29
30
|
require_relative "../chef"
|
30
31
|
require_relative "version"
|
@@ -211,6 +212,7 @@ module Shell
|
|
211
212
|
|
212
213
|
class Options
|
213
214
|
include Mixlib::CLI
|
215
|
+
include ChefConfig::Mixin::DotD
|
214
216
|
|
215
217
|
def self.footer(text = nil)
|
216
218
|
@footer = text if text
|
@@ -341,15 +343,44 @@ module Shell
|
|
341
343
|
# We have to nuke ARGV to make sure irb's option parser never sees it.
|
342
344
|
# otherwise, IRB complains about command line switches it doesn't recognize.
|
343
345
|
ARGV.clear
|
346
|
+
|
347
|
+
# This code should not exist.
|
348
|
+
# We should be using Application::Client and then calling load_config_file
|
349
|
+
# which does all this properly. However this will do for now.
|
344
350
|
config[:config_file] = config_file_for_shell_mode(environment)
|
345
351
|
config_msg = config[:config_file] || "none (standalone session)"
|
346
352
|
puts "loading configuration: #{config_msg}"
|
347
|
-
|
353
|
+
|
354
|
+
# load the config (if we have one)
|
355
|
+
unless config[:config_file].nil?
|
356
|
+
if File.exist?(config[:config_file]) && File.readable?(config[:config_file])
|
357
|
+
Chef::Config.from_file(config[:config_file])
|
358
|
+
end
|
359
|
+
|
360
|
+
# even if we couldn't load that, we need to tell Chef::Config what
|
361
|
+
# the file was so it sets conf dir and d_dir and such properly
|
362
|
+
Chef::Config[:config_file] = config[:config_file]
|
363
|
+
|
364
|
+
# now attempt to load any relevant dot-dirs
|
365
|
+
load_dot_d(Chef::Config[:client_d_dir]) if Chef::Config[:client_d_dir]
|
366
|
+
end
|
367
|
+
|
368
|
+
# finally merge command-line options in
|
348
369
|
Chef::Config.merge!(config)
|
349
370
|
end
|
350
371
|
|
351
372
|
private
|
352
373
|
|
374
|
+
# shamelessly lifted from application.rb
|
375
|
+
def apply_config(config_content, config_file_path)
|
376
|
+
Chef::Config.from_string(config_content, config_file_path)
|
377
|
+
rescue Exception => error
|
378
|
+
logger.fatal("Configuration error #{error.class}: #{error.message}")
|
379
|
+
filtered_trace = error.backtrace.grep(/#{Regexp.escape(config_file_path)}/)
|
380
|
+
filtered_trace.each { |line| logger.fatal(" " + line ) }
|
381
|
+
raise Chef::Exceptions::ConfigurationError.new("Aborting due to error in '#{config_file_path}': #{error}")
|
382
|
+
end
|
383
|
+
|
353
384
|
def config_file_for_shell_mode(environment)
|
354
385
|
dot_chef_dir = Chef::Util::PathHelper.home(".chef")
|
355
386
|
if config[:config_file]
|
@@ -105,7 +105,7 @@ class Chef::Util::DSC
|
|
105
105
|
# The name may not be null or empty, and should start with a letter.
|
106
106
|
def validate_configuration_name!(configuration_name)
|
107
107
|
if !!(configuration_name =~ /\A[A-Za-z]+[_a-zA-Z0-9]*\Z/) == false
|
108
|
-
raise ArgumentError,
|
108
|
+
raise ArgumentError, "Configuration `#{configuration_name}` is not a valid PowerShell cmdlet name"
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
data/lib/chef/version.rb
CHANGED
data/lib/chef/version_string.rb
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
require "chef-utils/version_string"
|
16
|
+
require "chef-utils/version_string" unless defined?(ChefUtils::VersionString)
|
17
17
|
|
18
18
|
class Chef
|
19
19
|
VersionString = ChefUtils::VersionString
|
@@ -19,10 +19,6 @@
|
|
19
19
|
require "spec_helper"
|
20
20
|
|
21
21
|
describe Chef::Resource::Ohai do
|
22
|
-
let(:ohai) do
|
23
|
-
OHAI_SYSTEM
|
24
|
-
end
|
25
|
-
|
26
22
|
let(:node) { Chef::Node.new }
|
27
23
|
|
28
24
|
let(:run_context) do
|
@@ -34,13 +30,9 @@ describe Chef::Resource::Ohai do
|
|
34
30
|
|
35
31
|
shared_examples_for "reloaded :uptime" do
|
36
32
|
it "should reload :uptime" do
|
37
|
-
|
38
|
-
|
39
|
-
# Sleep for a second so the uptime gets updated.
|
40
|
-
sleep 1
|
41
|
-
|
33
|
+
expect(node[:uptime_seconds]).to be nil
|
42
34
|
ohai_resource.run_action(:reload)
|
43
|
-
expect(node[:
|
35
|
+
expect(Integer(node[:uptime_seconds])).to be_an(Integer)
|
44
36
|
end
|
45
37
|
end
|
46
38
|
|
@@ -4,7 +4,7 @@ require "support/shared/integration/integration_helper"
|
|
4
4
|
require "chef/mixin/shell_out"
|
5
5
|
require "chef-utils/dist"
|
6
6
|
|
7
|
-
describe "chef-client with
|
7
|
+
describe "chef-client with compliance phase" do
|
8
8
|
|
9
9
|
include IntegrationSupport
|
10
10
|
include Chef::Mixin::ShellOut
|
@@ -46,6 +46,7 @@ describe "chef-client with audit mode" do
|
|
46
46
|
file "attributes.json", <<~FILE
|
47
47
|
{
|
48
48
|
"audit": {
|
49
|
+
"compliance_phase": true,
|
49
50
|
"json_file": {
|
50
51
|
"location": "#{report_file}"
|
51
52
|
},
|
@@ -223,6 +223,10 @@ module ResourceActionSpec
|
|
223
223
|
ActionJackson.succeeded = ActionJackson.ruby_block_converged
|
224
224
|
end
|
225
225
|
|
226
|
+
action :test1, description: "Original description" do
|
227
|
+
true
|
228
|
+
end
|
229
|
+
|
226
230
|
def foo_public
|
227
231
|
"foo_public!"
|
228
232
|
end
|
@@ -293,7 +297,12 @@ module ResourceActionSpec
|
|
293
297
|
ActionJackalope.jackalope_ran = :access_attribute
|
294
298
|
ActionJackalope.succeeded = ActionJackson.succeeded
|
295
299
|
end
|
300
|
+
|
301
|
+
action :test1, description: "An old action with a new description" do
|
302
|
+
super
|
303
|
+
end
|
296
304
|
end
|
305
|
+
|
297
306
|
before do
|
298
307
|
ActionJackalope.jackalope_ran = nil
|
299
308
|
ActionJackalope.load_current_resource_ran = nil
|
@@ -344,6 +353,11 @@ module ResourceActionSpec
|
|
344
353
|
expect(ActionJackalope.succeeded).to eq "foo!alope blarghle! bar!alope"
|
345
354
|
end
|
346
355
|
|
356
|
+
it "allows overridden action to have a description separate from the action defined in the base resource" do
|
357
|
+
expect(ActionJackson.action_description(:test1)).to eql "Original description"
|
358
|
+
expect(ActionJackalope.action_description(:test1)).to eql "An old action with a new description"
|
359
|
+
end
|
360
|
+
|
347
361
|
it "non-overridden actions run and can access overridden and non-overridden variables (but not necessarily new ones)" do
|
348
362
|
converge do
|
349
363
|
action_jackalope "hi" do
|
data/spec/spec_helper.rb
CHANGED
@@ -87,7 +87,7 @@ Dir["spec/support/**/*.rb"]
|
|
87
87
|
.each { |f| require f }
|
88
88
|
|
89
89
|
OHAI_SYSTEM = Ohai::System.new
|
90
|
-
OHAI_SYSTEM.all_plugins(["platform", "hostname", "languages/powershell"])
|
90
|
+
OHAI_SYSTEM.all_plugins(["platform", "hostname", "languages/powershell", "uptime"])
|
91
91
|
|
92
92
|
test_node = Chef::Node.new
|
93
93
|
test_node.automatic["os"] = (OHAI_SYSTEM["os"] || "unknown_os").dup.freeze
|
@@ -21,6 +21,14 @@ describe Chef::Compliance::Fetcher::Automate do
|
|
21
21
|
expect(res.target).to eq(expected)
|
22
22
|
end
|
23
23
|
|
24
|
+
it "should resolve a compliance URL with a @ in the namespace" do
|
25
|
+
res = Chef::Compliance::Fetcher::Automate.resolve("compliance://name@space/profile_name")
|
26
|
+
|
27
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::Automate)
|
28
|
+
expected = "https://automate.test/compliance/profiles/name@space/profile_name/tar"
|
29
|
+
expect(res.target).to eq(expected)
|
30
|
+
end
|
31
|
+
|
24
32
|
it "raises an exception with no data collector token" do
|
25
33
|
Chef::Config[:data_collector].delete(:token)
|
26
34
|
|
@@ -12,38 +12,86 @@ describe Chef::Compliance::Runner do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
describe "#enabled?" do
|
15
|
-
|
15
|
+
|
16
|
+
it "is true if the node attributes have audit profiles and the audit cookbook is not present, and the compliance mode attribute is nil" do
|
16
17
|
node.normal["audit"]["profiles"]["ssh"] = { 'compliance': "base/ssh" }
|
17
|
-
node.
|
18
|
+
node.normal["audit"]["compliance_phase"] = nil
|
18
19
|
|
19
20
|
expect(runner).to be_enabled
|
20
21
|
end
|
21
22
|
|
22
|
-
it "is
|
23
|
+
it "is true if the node attributes have audit profiles and the audit cookbook is not present, and the compliance mode attribute is true" do
|
23
24
|
node.normal["audit"]["profiles"]["ssh"] = { 'compliance': "base/ssh" }
|
24
|
-
node.
|
25
|
+
node.normal["audit"]["compliance_phase"] = true
|
26
|
+
|
27
|
+
expect(runner).to be_enabled
|
28
|
+
end
|
29
|
+
|
30
|
+
it "is false if the node attributes have audit profiles and the audit cookbook is not present, and the compliance mode attribute is false" do
|
31
|
+
node.normal["audit"]["profiles"]["ssh"] = { 'compliance': "base/ssh" }
|
32
|
+
node.normal["audit"]["compliance_phase"] = false
|
25
33
|
|
26
34
|
expect(runner).not_to be_enabled
|
27
35
|
end
|
28
36
|
|
29
|
-
it "is false if the node attributes
|
30
|
-
|
31
|
-
node.
|
37
|
+
it "is false if the node attributes have audit profiles and the audit cookbook is present, and the complince mode attribute is nil" do
|
38
|
+
stub_const("::Reporter::ChefAutomate", true)
|
39
|
+
node.normal["audit"]["profiles"]["ssh"] = { 'compliance': "base/ssh" }
|
40
|
+
node.normal["audit"]["compliance_phase"] = nil
|
32
41
|
|
33
42
|
expect(runner).not_to be_enabled
|
34
43
|
end
|
35
44
|
|
36
|
-
it "is
|
45
|
+
it "is true if the node attributes have audit profiles and the audit cookbook is present, and the complince mode attribute is true" do
|
46
|
+
stub_const("::Reporter::ChefAutomate", true)
|
47
|
+
node.normal["audit"]["profiles"]["ssh"] = { 'compliance': "base/ssh" }
|
48
|
+
node.normal["audit"]["compliance_phase"] = true
|
49
|
+
|
50
|
+
expect(runner).to be_enabled
|
51
|
+
end
|
52
|
+
|
53
|
+
it "is false if the node attributes do not have audit profiles and the audit cookbook is not present, and the complince mode attribute is nil" do
|
37
54
|
node.normal["audit"]["profiles"] = {}
|
55
|
+
node.normal["audit"]["compliance_phase"] = nil
|
56
|
+
|
57
|
+
expect(runner).not_to be_enabled
|
58
|
+
end
|
59
|
+
|
60
|
+
it "is false if the node attributes do not have audit profiles and the audit cookbook is present, and the complince mode attribute is nil" do
|
61
|
+
stub_const("::Reporter::ChefAutomate", true)
|
38
62
|
node.automatic["recipes"] = %w{ audit::default fancy_cookbook::fanciness tacobell::nachos }
|
63
|
+
node.normal["audit"]["compliance_phase"] = nil
|
39
64
|
|
40
65
|
expect(runner).not_to be_enabled
|
41
66
|
end
|
42
67
|
|
43
|
-
it "is false if the node attributes do not have audit attributes and the audit cookbook is not present" do
|
68
|
+
it "is false if the node attributes do not have audit attributes and the audit cookbook is not present, and the complince mode attribute is nil" do
|
44
69
|
node.automatic["recipes"] = %w{ fancy_cookbook::fanciness tacobell::nachos }
|
70
|
+
node.normal["audit"]["compliance_phase"] = nil
|
71
|
+
|
45
72
|
expect(runner).not_to be_enabled
|
46
73
|
end
|
74
|
+
|
75
|
+
it "is true if the node attributes do not have audit profiles and the audit cookbook is not present, and the complince mode attribute is true" do
|
76
|
+
node.normal["audit"]["profiles"] = {}
|
77
|
+
node.normal["audit"]["compliance_phase"] = true
|
78
|
+
|
79
|
+
expect(runner).to be_enabled
|
80
|
+
end
|
81
|
+
|
82
|
+
it "is true if the node attributes do not have audit profiles and the audit cookbook is present, and the complince mode attribute is true" do
|
83
|
+
stub_const("::Reporter::ChefAutomate", true)
|
84
|
+
node.automatic["recipes"] = %w{ audit::default fancy_cookbook::fanciness tacobell::nachos }
|
85
|
+
node.normal["audit"]["compliance_phase"] = true
|
86
|
+
|
87
|
+
expect(runner).to be_enabled
|
88
|
+
end
|
89
|
+
|
90
|
+
it "is true if the node attributes do not have audit attributes and the audit cookbook is not present, and the complince mode attribute is true" do
|
91
|
+
node.automatic["recipes"] = %w{ fancy_cookbook::fanciness tacobell::nachos }
|
92
|
+
node.normal["audit"]["compliance_phase"] = true
|
93
|
+
expect(runner).to be_enabled
|
94
|
+
end
|
47
95
|
end
|
48
96
|
|
49
97
|
describe "#inspec_profiles" do
|