From 761fa4338e4f59d389c13abef9b78a0a490be2e2 Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Tue, 7 Sep 2021 16:21:22 +0530 Subject: [PATCH 1/2] Fix - controls option was not working for depedent profile Signed-off-by: Vasu1105 --- lib/inspec/control_eval_context.rb | 36 +++++++++++++++++++++++++++++ lib/inspec/dsl.rb | 15 ++++++++++++ test/functional/inspec_exec_test.rb | 34 +++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) diff --git a/lib/inspec/control_eval_context.rb b/lib/inspec/control_eval_context.rb index 83acf639b..353bd4985 100644 --- a/lib/inspec/control_eval_context.rb +++ b/lib/inspec/control_eval_context.rb @@ -214,6 +214,18 @@ 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 + private def block_location(block, alternate_caller) @@ -250,5 +262,29 @@ module Inspec end id_exist_in_list end + + def tags_list_empty? + !@conf.empty? && @conf.key?("profile") && @conf["profile"].include_tags_list.empty? || @conf.empty? + end + + # Check if the given control exist in the --tags option + def tag_exist_in_control_tags?(tag_ids) + tag_option_matches_with_list = false + if !tag_ids.empty? && !tag_ids.nil? && profile_tag_config_exist? + tag_option_matches_with_list = !(tag_ids & @conf["profile"].include_tags_list).empty? + unless tag_option_matches_with_list + @conf["profile"].include_tags_list.any? do |inclusion| + # Try to see if the inclusion is a regex, and if it matches + if inclusion.is_a?(Regexp) + tag_ids.each do |id| + tag_option_matches_with_list = (inclusion =~ id) + break if tag_option_matches_with_list + end + end + end + end + end + tag_option_matches_with_list + end end end diff --git a/lib/inspec/dsl.rb b/lib/inspec/dsl.rb index c57f57091..d777f8ab7 100644 --- a/lib/inspec/dsl.rb +++ b/lib/inspec/dsl.rb @@ -93,8 +93,12 @@ 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 +<<<<<<< HEAD filter_included_controls(context, dep_entry.profile, opts, &block) if !opts[:include_all] || !(opts[:conf]["profile"].include_tags_list.empty?) +======= + filter_included_controls(context, dep_entry.profile, opts, &block) if !opts[:include_all] || !opts[:conf]["profile"].include_controls_list.empty? +>>>>>>> 9b8307fc0 (Fix - controls option was not working for depedent profile) # interpret the block and skip/modify as required context.load(block) if block_given? bind_context.add_subcontext(context) @@ -104,13 +108,24 @@ module Inspec::DSL mock = Inspec::Backend.create(Inspec::Config.mock) include_ctx = Inspec::ProfileContext.for_profile(profile, mock) include_ctx.load(block) if block_given? +<<<<<<< HEAD include_ctx.control_eval_context.conf = opts[:conf] +======= + # this sets the conf variable required in control_exist_in_control_list? method + include_ctx.control_eval_context.instance_variable_set(:@conf, opts[:conf]) +>>>>>>> 9b8307fc0 (Fix - controls option was not working for depedent profile) control_eval_ctx = include_ctx.control_eval_context # remove all rules that were not registered context.all_rules.each do |r| id = Inspec::Rule.rule_id(r) fid = Inspec::Rule.profile_id(r) + "/" + id if !opts[:include_all] && !(include_ctx.rules[id] || include_ctx.rules[fid]) +<<<<<<< HEAD +======= + context.remove_rule(fid) + elsif !control_eval_ctx.control_exist_in_controls_list?(id) + # filter the dependent profile controls which are not in the --controls options list +>>>>>>> 9b8307fc0 (Fix - controls option was not working for depedent profile) context.remove_rule(fid) elsif !control_eval_ctx.tags_list_empty? # filter included controls using --tags diff --git a/test/functional/inspec_exec_test.rb b/test/functional/inspec_exec_test.rb index ea03b47d2..e2376cf20 100644 --- a/test/functional/inspec_exec_test.rb +++ b/test/functional/inspec_exec_test.rb @@ -199,6 +199,40 @@ Test Summary: 0 successful, 0 failures, 0 skipped assert_exit_code 0, out end + # it filters the control from its depedent 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 depedent 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 depedent 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 "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") From 3e9223d6036629fda4c03ab24d2166e2463affe0 Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Tue, 7 Sep 2021 16:57:40 +0530 Subject: [PATCH 2/2] Fixed lint and failing test Signed-off-by: Vasu1105 --- lib/inspec/control_eval_context.rb | 46 ++++------------------------- lib/inspec/dsl.rb | 29 +++++++----------- test/functional/inspec_exec_test.rb | 24 +++++++++++---- 3 files changed, 34 insertions(+), 65 deletions(-) diff --git a/lib/inspec/control_eval_context.rb b/lib/inspec/control_eval_context.rb index 353bd4985..fdab2a5dd 100644 --- a/lib/inspec/control_eval_context.rb +++ b/lib/inspec/control_eval_context.rb @@ -226,6 +226,11 @@ module Inspec 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) @@ -245,46 +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 - - def tags_list_empty? - !@conf.empty? && @conf.key?("profile") && @conf["profile"].include_tags_list.empty? || @conf.empty? - end - - # Check if the given control exist in the --tags option - def tag_exist_in_control_tags?(tag_ids) - tag_option_matches_with_list = false - if !tag_ids.empty? && !tag_ids.nil? && profile_tag_config_exist? - tag_option_matches_with_list = !(tag_ids & @conf["profile"].include_tags_list).empty? - unless tag_option_matches_with_list - @conf["profile"].include_tags_list.any? do |inclusion| - # Try to see if the inclusion is a regex, and if it matches - if inclusion.is_a?(Regexp) - tag_ids.each do |id| - tag_option_matches_with_list = (inclusion =~ id) - break if tag_option_matches_with_list - end - end - end - end - end - tag_option_matches_with_list - end end end diff --git a/lib/inspec/dsl.rb b/lib/inspec/dsl.rb index d777f8ab7..9bd826ef4 100644 --- a/lib/inspec/dsl.rb +++ b/lib/inspec/dsl.rb @@ -93,12 +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 -<<<<<<< HEAD - filter_included_controls(context, dep_entry.profile, opts, &block) if !opts[:include_all] || !(opts[:conf]["profile"].include_tags_list.empty?) - -======= - filter_included_controls(context, dep_entry.profile, opts, &block) if !opts[:include_all] || !opts[:conf]["profile"].include_controls_list.empty? ->>>>>>> 9b8307fc0 (Fix - controls option was not working for depedent profile) + 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) @@ -108,26 +105,22 @@ module Inspec::DSL mock = Inspec::Backend.create(Inspec::Config.mock) include_ctx = Inspec::ProfileContext.for_profile(profile, mock) include_ctx.load(block) if block_given? -<<<<<<< HEAD include_ctx.control_eval_context.conf = opts[:conf] -======= - # this sets the conf variable required in control_exist_in_control_list? method - include_ctx.control_eval_context.instance_variable_set(:@conf, opts[:conf]) ->>>>>>> 9b8307fc0 (Fix - controls option was not working for depedent profile) control_eval_ctx = include_ctx.control_eval_context # remove all rules that were not registered context.all_rules.each do |r| id = Inspec::Rule.rule_id(r) fid = Inspec::Rule.profile_id(r) + "/" + id if !opts[:include_all] && !(include_ctx.rules[id] || include_ctx.rules[fid]) -<<<<<<< HEAD -======= context.remove_rule(fid) - elsif !control_eval_ctx.control_exist_in_controls_list?(id) - # filter the dependent profile controls which are not in the --controls options list ->>>>>>> 9b8307fc0 (Fix - controls option was not working for depedent profile) - 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) diff --git a/test/functional/inspec_exec_test.rb b/test/functional/inspec_exec_test.rb index e2376cf20..5173e48ff 100644 --- a/test/functional/inspec_exec_test.rb +++ b/test/functional/inspec_exec_test.rb @@ -199,9 +199,9 @@ Test Summary: 0 successful, 0 failures, 0 skipped assert_exit_code 0, out end - # it filters the control from its depedent profile_c + # 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/'") + 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" @@ -210,9 +210,9 @@ Test Summary: 0 successful, 0 failures, 0 skipped assert_exit_code 0, out end - # it filters the control from its depedent profile_c + # 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'") + 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" @@ -221,9 +221,9 @@ Test Summary: 0 successful, 0 failures, 0 skipped assert_exit_code 0, out end - # it filters the control from its depedent profile_c + # 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'") + 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" @@ -233,6 +233,18 @@ 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 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")