Merge pull request #5643 from inspec/nm/tags-fix

Fix tags processing issue in profiles
This commit is contained in:
Clinton Wolfe 2021-08-31 23:40:56 -04:00 committed by GitHub
commit 28956c0cf5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 9 deletions

View file

@ -337,7 +337,7 @@ This subcommand has additional options:
* ``--target-id=TARGET_ID``
Provide a ID which will be included on reports
* ``--tags=one two three``
A list of tags, a list of regular expressions that match tags, or a hash map where each value is a tag. `exec` will run controls referenced by the listed or matching tags.
A list of tags, a list of regular expressions that match tags. `exec` will run controls referenced by the listed or matching tags.
* ``--user=USER``
The login user for a remote scan.
* ``--vendor-cache=VENDOR_CACHE``

View file

@ -53,19 +53,26 @@ module Inspec
def control(id, opts = {}, &block)
opts[:skip_only_if_eval] = @skip_only_if_eval
tag_ids = control_tags(&block)
if (controls_list_empty? && tags_list_empty?) || control_exist_in_controls_list?(id) || tag_exist_in_control_tags?(tag_ids)
if (controls_list_empty? && tags_list_empty?) || control_exist_in_controls_list?(id)
register_control(Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block))
elsif !tags_list_empty?
# Inside elsif rule is initialised before registering it because it enables fetching of control tags
# This condition is only true when --tags option is used
inspec_rule = Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block)
tag_ids = control_tags(inspec_rule)
register_control(inspec_rule) if tag_exist_in_control_tags?(tag_ids)
end
end
alias rule control
def control_tags(&block)
tag_source = block.source.split("\n").select { |src| src.split.first.eql?("tag") }
tag_source = tag_source.map { |src| src.sub("tag", "").strip }.map { |src| src.split(",").map { |final_src| final_src.sub(/([^:]*):/, "") } }.flatten
output = tag_source.map { |src| src.sub(/\[|\]/, "") }.map { |src| instance_eval(src) }
output.compact.uniq
def control_tags(inspec_rule)
all_tags = []
inspec_rule.tag.each do |key, value|
all_tags.push(key)
all_tags.push(value) unless value.nil?
end
all_tags.flatten.compact.uniq.map(&:to_s)
rescue
[]
end

View file

@ -1,8 +1,16 @@
control "basic" do
tag "tag1"
tag :symbol_key1, :symbol_key2
tag severity: nil
tag data: "tag2"
tag data_arr: ["tag3", "tag4"]
tag error1: "Line with a line-feed
error"
tag error2: "Line with a comma,error"
tag cci: ['CCI-000366']
tag legacy: []
tag nist: ["AU-9", "AU-9 (3)", "AC-3 (4)", "AC-6 (10)"]
tag ref: "http:example.html:CIS CSC v6.0 #5.1;"
describe(true) { it { should eq true } }
end

View file

@ -258,7 +258,7 @@ Test Summary: 0 successful, 0 failures, 0 skipped
it "executes only specified controls when selecting the controls by using regex on tags" do
inspec("exec " + File.join(profile_path, "control-tags") + " --no-create-lockfile --tags '/\s+/'")
_(stdout).must_include "true is expected to eq true\n"
_(stdout).must_include "Test Summary: 1 successful, 0 failures, 0 skipped\n"
_(stdout).must_include "Test Summary: 2 successful, 0 failures, 0 skipped\n"
_(stderr).must_equal ""
assert_exit_code 0, out
@ -282,6 +282,15 @@ Test Summary: 0 successful, 0 failures, 0 skipped
assert_exit_code 100, out
end
it "executes profile successfully when tags are used with single element array, punctuations and linefeeds" do
inspec("exec " + File.join(profile_path, "control-tags") + " --no-create-lockfile --tags tag1 'Line with a comma,error' CCI-000366")
_(stdout).must_include "true is expected to eq true\n"
_(stdout).must_include "Test Summary: 1 successful, 0 failures, 0 skipped\n"
_(stderr).must_equal ""
assert_exit_code 0, out
end
it "reports whan a profile cannot be loaded" do
inspec("exec " + File.join(profile_path, "raise_outside_control") + " --no-create-lockfile")
_(stdout).must_match(/Profile:[\W]+InSpec Profile \(raise_outside_control\)/)