Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for --controls option is not working as expected. #5434

Merged
merged 13 commits into from Mar 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 29 additions & 3 deletions lib/inspec/control_eval_context.rb
Expand Up @@ -53,8 +53,9 @@ def profile_name

def control(id, opts = {}, &block)
opts[:skip_only_if_eval] = @skip_only_if_eval

register_control(Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block))
if control_exist_in_controls_list?(id) || controls_list_empty?
register_control(Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block))
end
end
alias rule control

Expand All @@ -68,10 +69,14 @@ def describe(*args, &block)
id = "(generated from #{loc} #{SecureRandom.hex})"

res = nil

rule = Inspec::Rule.new(id, profile_id, resources_dsl, {}) do
res = describe(*args, &block)
end
register_control(rule, &block)

if control_exist_in_controls_list?(id) || controls_list_empty?
register_control(rule, &block)
end

res
end
Expand Down Expand Up @@ -176,5 +181,26 @@ def block_location(block, alternate_caller)
"#{File.basename(path)}:#{line}"
end
end

# Returns true if configuration hash is not empty and it contains the list of controls is not empty
def profile_config_exist?
!@conf.empty? && @conf.key?("profile") && !@conf["profile"].include_controls_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)
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
26 changes: 11 additions & 15 deletions lib/inspec/profile.rb
Expand Up @@ -225,36 +225,32 @@ def collect_tests(include_list = @controls)
end
@tests_collected = true
end
filter_controls(@runner_context.all_rules, include_list)
@runner_context.all_rules
end

def filter_controls(controls_array, include_list)
return controls_array if include_list.nil? || include_list.empty?
# This creates the list of controls provided in the --controls options which need to be include
# for evaluation.
def include_controls_list
return [] if @controls.nil? || @controls.empty?

included_controls = @controls
# Check for anything that might be a regex in the list, and make it official
include_list.each_with_index do |inclusion, index|
included_controls.each_with_index do |inclusion, index|
next if inclusion.is_a?(Regexp)
# Insist the user wrap the regex in slashes to demarcate it as a regex
next unless inclusion.start_with?("/") && inclusion.end_with?("/")

inclusion = inclusion[1..-2] # Trim slashes
begin
re = Regexp.new(inclusion)
include_list[index] = re
included_controls[index] = re
rescue RegexpError => e
warn "Ignoring unparseable regex '/#{inclusion}/' in --control CLI option: #{e.message}"
include_list[index] = nil
end
end
include_list.compact!

controls_array.select do |c|
id = ::Inspec::Rule.rule_id(c)
include_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)
included_controls[index] = nil
end
end
included_controls.compact!
included_controls
end

def load_libraries
Expand Down
30 changes: 30 additions & 0 deletions test/fixtures/profiles/controls-option-test/controls/example.rb
@@ -0,0 +1,30 @@
control "foo" do
describe 'a thing' do
it { should cmp 'a thing' }
end
end

control "bar" do
puts 'bar'
describe 'a thing' do
it { should cmp 'a thing' }
end
end

control "11_pass" do
describe 'a thing' do
it { should cmp 'a thing' }
end
end

control "11_pass2" do
describe 'a thing' do
it { should cmp 'a thing' }
end
end

describe 'a thing' do
puts 'only-describe'
it { should cmp 'a thing' }
end

10 changes: 10 additions & 0 deletions test/fixtures/profiles/controls-option-test/inspec.yml
@@ -0,0 +1,10 @@
name: controls-option-test
title: InSpec Profile
maintainer: The Authors
copyright: The Authors
copyright_email: you@example.com
license: Apache-2.0
summary: An InSpec Compliance Profile
version: 0.1.0
supports:
platform: os
1 change: 1 addition & 0 deletions test/fixtures/profiles/inputs/cli/inspec.yml
Expand Up @@ -8,3 +8,4 @@ supports:
inputs:
- name: test_input_04
type: numeric
value: 0.0
21 changes: 21 additions & 0 deletions test/functional/inspec_exec_test.rb
Expand Up @@ -178,6 +178,27 @@ def stderr
assert_exit_code 100, out
end

it "executes only specified controls when selecting the controls by literal names" do
inspec("exec " + File.join(profile_path, "controls-option-test") + " --no-create-lockfile --controls foo")
_(out.stdout).must_include "foo"
_(out.stdout).wont_include "bar"
_(out.stdout).wont_include "only-describe"
_(stderr).must_equal ""

assert_exit_code 0, out
end

it "executes only specified controls when selecting the controls by regex" do
inspec("exec " + File.join(profile_path, "controls-option-test") + " --no-create-lockfile --controls '/^11_pass/'")
_(out.stdout).must_include "11_pass"
_(out.stdout).must_include "11_pass2"
_(out.stdout).wont_include "bar"
_(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")

Expand Down