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`` * ``--target-id=TARGET_ID``
Provide a ID which will be included on reports Provide a ID which will be included on reports
* ``--tags=one two three`` * ``--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`` * ``--user=USER``
The login user for a remote scan. The login user for a remote scan.
* ``--vendor-cache=VENDOR_CACHE`` * ``--vendor-cache=VENDOR_CACHE``

View file

@ -53,19 +53,26 @@ module Inspec
def control(id, opts = {}, &block) def control(id, opts = {}, &block)
opts[:skip_only_if_eval] = @skip_only_if_eval 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)
if (controls_list_empty? && tags_list_empty?) || control_exist_in_controls_list?(id) || tag_exist_in_control_tags?(tag_ids)
register_control(Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block)) 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
end end
alias rule control alias rule control
def control_tags(&block) def control_tags(inspec_rule)
tag_source = block.source.split("\n").select { |src| src.split.first.eql?("tag") } all_tags = []
tag_source = tag_source.map { |src| src.sub("tag", "").strip }.map { |src| src.split(",").map { |final_src| final_src.sub(/([^:]*):/, "") } }.flatten inspec_rule.tag.each do |key, value|
output = tag_source.map { |src| src.sub(/\[|\]/, "") }.map { |src| instance_eval(src) } all_tags.push(key)
output.compact.uniq all_tags.push(value) unless value.nil?
end
all_tags.flatten.compact.uniq.map(&:to_s)
rescue rescue
[] []
end end

View file

@ -1,8 +1,16 @@
control "basic" do control "basic" do
tag "tag1" tag "tag1"
tag :symbol_key1, :symbol_key2
tag severity: nil tag severity: nil
tag data: "tag2" tag data: "tag2"
tag data_arr: ["tag3", "tag4"] 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 } } describe(true) { it { should eq true } }
end 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 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+/'") 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 "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 "" _(stderr).must_equal ""
assert_exit_code 0, out assert_exit_code 0, out
@ -282,6 +282,15 @@ Test Summary: 0 successful, 0 failures, 0 skipped
assert_exit_code 100, out assert_exit_code 100, out
end 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 it "reports whan a profile cannot be loaded" do
inspec("exec " + File.join(profile_path, "raise_outside_control") + " --no-create-lockfile") inspec("exec " + File.join(profile_path, "raise_outside_control") + " --no-create-lockfile")
_(stdout).must_match(/Profile:[\W]+InSpec Profile \(raise_outside_control\)/) _(stdout).must_match(/Profile:[\W]+InSpec Profile \(raise_outside_control\)/)