Merge pull request #5656 from inspec/vasundhara/fix-dependent-profile-control-filtering

Fix --controls option was not working for dependent profile
This commit is contained in:
Clinton Wolfe 2021-09-28 08:14:03 -04:00 committed by GitHub
commit 67afbc5f59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 74 additions and 20 deletions

View file

@ -214,6 +214,23 @@ module Inspec
!@conf.empty? && @conf.key?("profile") && @conf["profile"].include_tags_list.empty? || @conf.empty?
end
# Check if the given control exist in the --controls option
def control_exist_in_controls_list?(id)
id_exist_in_list = false
if profile_config_exist?
id_exist_in_list = @conf["profile"].include_controls_list.any? do |inclusion|
# Try to see if the inclusion is a regex, and if it matches
inclusion == id || (inclusion.is_a?(Regexp) && inclusion =~ id)
end
end
id_exist_in_list
end
# Returns true if configuration hash is empty or configuration hash does not have the list of controls that needs to be included
def controls_list_empty?
!@conf.empty? && @conf.key?("profile") && @conf["profile"].include_controls_list.empty? || @conf.empty?
end
private
def block_location(block, alternate_caller)
@ -233,22 +250,5 @@ module Inspec
def profile_tag_config_exist?
!@conf.empty? && @conf.key?("profile") && !@conf["profile"].include_tags_list.empty?
end
# Returns true if configuration hash is empty or configuration hash does not have the list of controls that needs to be included
def controls_list_empty?
!@conf.empty? && @conf.key?("profile") && @conf["profile"].include_controls_list.empty? || @conf.empty?
end
# Check if the given control exist in the --controls option
def control_exist_in_controls_list?(id)
id_exist_in_list = false
if profile_config_exist?
id_exist_in_list = @conf["profile"].include_controls_list.any? do |inclusion|
# Try to see if the inclusion is a regex, and if it matches
inclusion == id || (inclusion.is_a?(Regexp) && inclusion =~ id)
end
end
id_exist_in_list
end
end
end

View file

@ -93,8 +93,9 @@ module Inspec::DSL
context = dep_entry.profile.runner_context
# if we don't want all the rules, then just make 1 pass to get all rule_IDs
# that we want to keep from the original
filter_included_controls(context, dep_entry.profile, opts, &block) if !opts[:include_all] || !(opts[:conf]["profile"].include_tags_list.empty?)
if !opts[:include_all] || !(opts[:conf]["profile"].include_tags_list.empty?) || !opts[:conf]["profile"].include_controls_list.empty?
filter_included_controls(context, dep_entry.profile, opts, &block)
end
# interpret the block and skip/modify as required
context.load(block) if block_given?
bind_context.add_subcontext(context)
@ -112,7 +113,14 @@ module Inspec::DSL
fid = Inspec::Rule.profile_id(r) + "/" + id
if !opts[:include_all] && !(include_ctx.rules[id] || include_ctx.rules[fid])
context.remove_rule(fid)
elsif !control_eval_ctx.tags_list_empty?
end
unless control_eval_ctx.controls_list_empty?
# filter the dependent profile controls which are not in the --controls options list
context.remove_rule(fid) unless control_eval_ctx.control_exist_in_controls_list?(id)
end
unless control_eval_ctx.tags_list_empty?
# filter included controls using --tags
tag_ids = control_eval_ctx.control_tags(r)
context.remove_rule(fid) unless control_eval_ctx.tag_exist_in_control_tags?(tag_ids)

View file

@ -199,6 +199,52 @@ Test Summary: 0 successful, 0 failures, 0 skipped
assert_exit_code 0, out
end
# it filters the control from its dependent profile_c
it "executes only specified controls from parent and child profile when selecting the controls by regex" do
inspec("exec " + File.join(profile_path, "dependencies", "profile_a") + " --no-create-lockfile --controls '/^profilec/'")
_(out.stdout).must_include "profilec-1"
_(out.stdout).wont_include "profilea-1"
_(out.stdout).wont_include "only-describe"
_(stderr).must_equal ""
assert_exit_code 0, out
end
# it filters the control from its dependent profile_c
it "executes only specified controls from parent and child profile when selecting the controls by id" do
inspec("exec " + File.join(profile_path, "dependencies", "profile_a") + " --no-create-lockfile --controls 'profilec-1'")
_(out.stdout).must_include "profilec-1"
_(out.stdout).wont_include "profilea-1"
_(out.stdout).wont_include "only-describe"
_(stderr).must_equal ""
assert_exit_code 0, out
end
# it filters the control from its dependent profile_c
it "executes only specified controls from parent and child profile when selecting the controls by space seprated id" do
inspec("exec " + File.join(profile_path, "dependencies", "profile_a") + " --no-create-lockfile --controls 'profilec-1' 'profilea-1'")
_(out.stdout).must_include "profilec-1"
_(out.stdout).must_include "profilea-1"
_(out.stdout).wont_include "profilea-2"
_(out.stdout).wont_include "only-describe"
_(stderr).must_equal ""
assert_exit_code 0, out
end
# it filters the control from its dependent profile_c
it "executes only specified controls of required dependent profile when selecting the controls by space seprated id" do
inspec("exec " + File.join(profile_path, "dependencies", "require_controls_test") + " --no-create-lockfile --controls 'profileb-2'")
_(out.stdout).must_include "profileb-2"
_(out.stdout).wont_include "profilea-1"
_(out.stdout).wont_include "profilea-2"
_(out.stdout).wont_include "only-describe"
_(stderr).must_equal ""
assert_exit_code 0, out
end
it "executes only specified controls when selecting passing controls by literal names" do
inspec("exec " + File.join(profile_path, "filter_table") + " --no-create-lockfile --controls 2943_pass_undeclared_field_in_hash 2943_pass_irregular_row_key")