mirror of
https://github.com/inspec/inspec
synced 2024-11-27 15:10:44 +00:00
Merge pull request #618 from chef/dr/only_if
don't remove controls with only_if
This commit is contained in:
commit
bf8a09b864
2 changed files with 74 additions and 19 deletions
|
@ -102,6 +102,7 @@ module Inspec
|
||||||
def initialize(backend, conf) # rubocop:disable Lint/NestedMethodDefinition, Lint/DuplicateMethods
|
def initialize(backend, conf) # rubocop:disable Lint/NestedMethodDefinition, Lint/DuplicateMethods
|
||||||
@backend = backend
|
@backend = backend
|
||||||
@conf = conf
|
@conf = conf
|
||||||
|
@skip_profile = false
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method :title do |arg|
|
define_method :title do |arg|
|
||||||
|
@ -115,20 +116,7 @@ module Inspec
|
||||||
define_method :control do |*args, &block|
|
define_method :control do |*args, &block|
|
||||||
id = args[0]
|
id = args[0]
|
||||||
opts = args[1] || {}
|
opts = args[1] || {}
|
||||||
|
register_control(rule_class.new(id, opts, &block))
|
||||||
# Skip the control if the resource triggered a skip;
|
|
||||||
# However: when this is run on a mock backend, do not skip it.
|
|
||||||
# This is e.g. relevant for JSON generation, where we need all
|
|
||||||
# controls.
|
|
||||||
return if @skip_profile && os[:family] != 'unknown'
|
|
||||||
|
|
||||||
profile_context_owner.register_rule(rule_class.new(id, opts, &block))
|
|
||||||
end
|
|
||||||
|
|
||||||
alias_method :rule, :control
|
|
||||||
|
|
||||||
define_method :register_control do |control|
|
|
||||||
profile_context_owner.register_rule(control) unless control.nil?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method :describe do |*args, &block|
|
define_method :describe do |*args, &block|
|
||||||
|
@ -139,10 +127,24 @@ module Inspec
|
||||||
rule = rule_class.new(id, {}) do
|
rule = rule_class.new(id, {}) do
|
||||||
res = describe(*args, &block)
|
res = describe(*args, &block)
|
||||||
end
|
end
|
||||||
profile_context_owner.register_rule(rule, &block)
|
register_control(rule, &block)
|
||||||
res
|
res
|
||||||
end
|
end
|
||||||
|
|
||||||
|
define_method :register_control do |control, &block|
|
||||||
|
profile_context_owner.register_rule(control, &block) unless control.nil?
|
||||||
|
|
||||||
|
# Skip the control if the resource triggered a skip;
|
||||||
|
if @skip_profile
|
||||||
|
control.instance_variable_set(:@checks, [])
|
||||||
|
# TODO: we use os as the carrier here, but should consider
|
||||||
|
# a separate resource to do skipping
|
||||||
|
resource = os
|
||||||
|
resource.skip_resource('Skipped control due to only_if condition.')
|
||||||
|
control.describe(resource)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# TODO: mock method for attributes; import attribute handling
|
# TODO: mock method for attributes; import attribute handling
|
||||||
define_method :attributes do |_name, _options|
|
define_method :attributes do |_name, _options|
|
||||||
nil
|
nil
|
||||||
|
@ -152,13 +154,14 @@ module Inspec
|
||||||
profile_context_owner.unregister_rule(id)
|
profile_context_owner.unregister_rule(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
alias_method :skip_rule, :skip_control
|
|
||||||
|
|
||||||
def only_if
|
def only_if
|
||||||
return unless block_given?
|
return unless block_given?
|
||||||
@skip_profile = !yield
|
@skip_profile ||= !yield
|
||||||
end
|
end
|
||||||
|
|
||||||
|
alias_method :rule, :control
|
||||||
|
alias_method :skip_rule, :skip_control
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def block_location(block, alternate_caller)
|
def block_location(block, alternate_caller)
|
||||||
|
|
|
@ -117,7 +117,59 @@ describe Inspec::ProfileContext do
|
||||||
load('expect(true).to_eq true').must_raise NoMethodError
|
load('expect(true).to_eq true').must_raise NoMethodError
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'provides the rule keyword in the global DSL' do
|
describe 'global only_if' do
|
||||||
|
let(:if_true) { "only_if { true }\n" }
|
||||||
|
let(:if_false) { "only_if { false }\n" }
|
||||||
|
let(:describe) { "describe nil do its(:to_i) { should eq rand } end\n" }
|
||||||
|
let(:control) { "control 1 do\n#{describe}end" }
|
||||||
|
|
||||||
|
it 'provides the keyword' do
|
||||||
|
profile.load(if_true)
|
||||||
|
profile.rules.must_equal({})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'doesnt affect controls when positive' do
|
||||||
|
profile.load(if_true + 'control 1')
|
||||||
|
profile.rules.values[0].must_be_kind_of Inspec::Rule
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'doesnt remove controls when negative' do
|
||||||
|
profile.load(if_false + 'control 1')
|
||||||
|
profile.rules.values[0].must_be_kind_of Inspec::Rule
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'alters controls when positive' do
|
||||||
|
profile.load(if_false + control)
|
||||||
|
get_checks.length.must_equal 1
|
||||||
|
get_checks[0][1][0].resource_skipped.must_equal 'Skipped control due to only_if condition.'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'alters non-controls when positive' do
|
||||||
|
profile.load(if_false + describe)
|
||||||
|
get_checks.length.must_equal 1
|
||||||
|
get_checks[0][1][0].resource_skipped.must_equal 'Skipped control due to only_if condition.'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'doesnt alter controls when negative' do
|
||||||
|
profile.load(if_true + control)
|
||||||
|
get_checks.length.must_equal 1
|
||||||
|
get_checks[0][1][0].must_be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'doesnt alter non-controls when negative' do
|
||||||
|
profile.load(if_true + describe)
|
||||||
|
get_checks.length.must_equal 1
|
||||||
|
get_checks[0][1][0].must_be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'provides the control keyword in the global DSL' do
|
||||||
|
profile.load('control 1')
|
||||||
|
profile.rules.keys.must_equal [1]
|
||||||
|
profile.rules.values[0].must_be_kind_of Inspec::Rule
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'provides the rule keyword in the global DSL (legacy mode)' do
|
||||||
profile.load('rule 1')
|
profile.load('rule 1')
|
||||||
profile.rules.keys.must_equal [1]
|
profile.rules.keys.must_equal [1]
|
||||||
profile.rules.values[0].must_be_kind_of Inspec::Rule
|
profile.rules.values[0].must_be_kind_of Inspec::Rule
|
||||||
|
|
Loading…
Reference in a new issue