CHEF-5200 Waived controls are not getting waived (skipped) in case of failure at resource level. (#6588)

* CHEF-5200: This fix applies waiver if exception occurs while eval the control inside control block. This ensures that waiver are got applied in case of resouce level failures too.

Signed-off-by: Vasu1105 <vasundhara.jagdale@chef.io>

* When waiver file is empty error should be raised the written is invalid for the empty waiver file.
Added different test to check only_if waiver is applied when the waived control in the waived file has expired.

Signed-off-by: Vasu1105 <vasundhara.jagdale@chef.io>

* Fix lint

Signed-off-by: Vasu1105 <vasundhara.jagdale@chef.io>

* Fix test failing on windows due to different exit code on the Windows.

Signed-off-by: Vasu1105 <vasundhara.jagdale@chef.io>

---------

Signed-off-by: Vasu1105 <vasundhara.jagdale@chef.io>
This commit is contained in:
Vasundhara Jagdale 2023-08-09 19:20:49 +05:30 committed by GitHub
parent 5c5d5581ad
commit e861b37a59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 8 deletions

View file

@ -63,6 +63,11 @@ module Inspec
# Rubocop thinks we are raising an exception - we're actually calling RSpec's fail()
its(location) { fail e.message } # rubocop: disable Style/SignalException
end
# instance_eval evaluates the describe block and raise errors if at the resource level any execution is failed
# Waived controls expect not to raise any controls and get skipped if run is false so __apply_waivers needs to be called here too
# so that waived control are actually gets waived.
__apply_waivers
end
end

View file

@ -19,15 +19,17 @@ module Inspec
data = nil
if [".yaml", ".yml"].include? file_extension
data = Secrets::YAML.resolve(file_path)
data = data.inputs unless data.nil?
validate_json_yaml(data)
unless data.nil?
data = data.inputs
validate_json_yaml(data)
end
elsif file_extension == ".csv"
data = Waivers::CSVFileReader.resolve(file_path)
headers = Waivers::CSVFileReader.headers
validate_headers(headers)
elsif file_extension == ".json"
data = Waivers::JSONFileReader.resolve(file_path)
validate_json_yaml(data)
validate_json_yaml(data) unless data.nil?
end
output.merge!(data) if !data.nil? && data.is_a?(Hash)

View file

@ -7,3 +7,10 @@ control "01_only_if" do
it { should eq true }
end
end
control "02_only_if_when_waiver_is_expired" do
only_if("test_message_from_dsl_02_only_if") { false }
describe true do
it { should eq true }
end
end

View file

@ -1,3 +1,8 @@
01_only_if:
run: false
justification: test_message_from_waiver
02_only_if_when_waiver_is_expired:
expiration_date: 1977-06-01
run: false
justification: test_message_from_waiver

View file

@ -72,8 +72,8 @@ describe "waivers" do
assert_empty act
end
def assert_skip_message(yea, nay)
msg = controls_by_id.dig("01_only_if", "results", 0, "skip_message")
def assert_skip_message(yea, nay, control_id = "01_only_if")
msg = controls_by_id.dig(control_id, "results", 0, "skip_message")
assert_includes msg, yea
refute_includes msg, nay
end
@ -241,10 +241,24 @@ describe "waivers" do
describe "waivers and only_if" do
let(:profile_name) { "only_if" }
describe "when an only_if is used with no waiver" do
describe "when an only_if is used with empty waiver file" do
let(:waiver_file) { "empty.yaml" }
it "skips the control with an only_if message" do
assert_skip_message "due to only_if", "waiver"
it "raise unable to parse empty.yaml file error" do
result = run_result
assert_includes result.stderr, "unable to parse"
if windows?
assert_equal 1, result.exit_status
else
assert_equal 102, result.exit_status
end
end
end
describe "when an only_if is used with waiver file which has waived control with past expiration date" do
let(:waiver_file) { "waiver.yaml" }
it "skips the control with a waiver message" do
assert_skip_message "test_message_from_dsl_02_only_if", "waiver", "02_only_if_when_waiver_is_expired"
end
end