Supply resource name, params to code_desc

Signed-off-by: Nick Schwaderer <nschwaderer@chef.io>
This commit is contained in:
Nick Schwaderer 2020-09-04 08:59:01 +01:00
parent 23ac60e7ae
commit 345a832eb1
13 changed files with 61 additions and 8 deletions

View file

@ -486,6 +486,7 @@ The `run_data` object contains all data from the Chef InSpec run. Here is an ove
v0.1.0 - Initial version
v0.2.0 - added `run_data.profiles[0].inputs[0].options.sensitive`
v0.3.0 - added resource_name && params
## Implementing Input Plugins

View file

@ -159,6 +159,14 @@ module Inspec::Formatters
resource_title: example.metadata[:described_class] || example.metadata[:example_group][:description],
expectation_message: format_expectation_message(example),
waiver_data: example.metadata[:waiver_data],
# This enforces the resource name as expected based off of the class
# name. However, if we wanted the `name` attribute against the class
# to be canonical for this case (consider edge cases!) we would use
# example.metadata[:described_class].instance_variable_get(:@__resource_name__)&.to_s
resource_class: example.metadata[:described_class].class.superclass.name,
# This is a raw grep of the text passed to the resource in any format,
# and is used to enforce near-uniqueness against the resource.
resource_params: find_resource_params(example.metadata[:described_class]),
}
unless (pid = example.metadata[:profile_id]).nil?
@ -174,6 +182,14 @@ module Inspec::Formatters
res
end
def find_resource_params(example)
if example.class.ancestors.include?(Inspec::Resource)
example.instance_variable_get(:@resource_params)
else
[]
end
end
def format_expectation_message(example)
if (example.metadata[:example_group][:description_args].first == example.metadata[:example_group][:described_class]) ||
example.metadata[:example_group][:described_class].nil?

View file

@ -40,6 +40,8 @@ module Inspec::Reporters
message: r[:message],
exception: r[:exception],
backtrace: r[:backtrace],
resource_class: r[:resource_class],
resource_params: r[:resource_params].to_s,
}.reject { |_k, v| v.nil? }
}
end

View file

@ -108,6 +108,7 @@ module Inspec
# Infrastructure / Bookkeeping
def self.__register(name, resource_klass)
# This has bitten us and should be a great candidate to remove in InSpec5
cl = Class.new(resource_klass) do # TODO: remove
# As best I can figure out, this anonymous class only exists
# because we're trying to avoid having resources with
@ -116,6 +117,7 @@ module Inspec
# documentation.
def initialize(backend, name, *args)
supersuper_initialize(backend, name) do
@resource_params = args
super(*args)
end
end

View file

@ -47,7 +47,7 @@ module Inspec
# core reporters have been migrated to plugins. It is probable that new data elements
# and new Hash compatibility behavior will be added during the core reporter plugin
# conversion process.
SCHEMA_VERSION = "0.2.0".freeze
SCHEMA_VERSION = "0.3.0".freeze
def self.compatible_schema?(constraints)
reqs = Gem::Requirement.create(constraints)

View file

@ -8,6 +8,7 @@ module Inspec
:run_time, # Float seconds execution time
:skip_message, # String
:start_time, # DateTime
:resource_params, # What is passed to the resource as a raw grep
:status, # String
:resource_title, # Ugly internals
# :waiver_data, # Undocumented tramp data / not exposed in this API
@ -34,6 +35,7 @@ module Inspec
end
self.resource_name = raw_res_data[:resource_title].instance_variable_get(:@__resource_name__)&.to_s
self.resource_params = raw_res_data[:resource_title].instance_variable_get(:@grep)&.to_s
end
end
end

View file

@ -56,6 +56,7 @@ module Inspec
"code_desc" => { "type" => "string" },
"run_time" => { "type" => "number" },
"start_time" => { "type" => "string" },
"resource_class" => { "type" => "string", "optional" => true },
"skip_message" => { "type" => "string", "optional" => true },
"resource" => { "type" => "string", "optional" => true },
"message" => { "type" => "string", "optional" => true },
@ -194,6 +195,7 @@ module Inspec
"profile_sha256" => { "type" => "string" },
"status" => { "type" => "string" },
"code_desc" => { "type" => "string" },
"resource_class" => { "type" => "string", "optional" => true },
"skip_message" => { "type" => "string", "optional" => true },
"resource" => { "type" => "string", "optional" => true },
"message" => { "type" => "string", "optional" => true },

View file

@ -61,7 +61,8 @@
"status": "passed",
"code_desc": "File /etc/hosts mode should eq 420",
"run_time": 0.031503,
"start_time": "2018-07-30T08:56:41-04:00"
"start_time": "2018-07-30T08:56:41-04:00",
"resource_params": ""
}
]
},
@ -101,7 +102,8 @@
"status": "passed",
"code_desc": "File /etc/passwd should exist",
"run_time": 0.003954,
"start_time": "2018-07-30T08:56:41-04:00"
"start_time": "2018-07-30T08:56:41-04:00",
"resource_params": ""
}
]
},
@ -131,7 +133,8 @@
"run_time": 2.9e-05,
"start_time": "2018-07-30T08:56:41-04:00",
"resource": "Operating System Detection",
"skip_message": "Skipped control due to only_if condition."
"skip_message": "Skipped control due to only_if condition.",
"resource_params": ""
}
]
}

View file

@ -1 +1 @@
{"platform":{"name":"mac_os_x","release":"17.2.0"},"profiles":[{"name":"long_commands","version":"0.1.0","sha256":"4f816f8cf18f165f05f1cf20936aaad06a15287de3f578891197647ca05c7df4","title":"InSpec Profile","maintainer":"The Authors","summary":"An InSpec Compliance Profile","license":"Apache-2.0","copyright":"The Authors","copyright_email":"you@example.com","supports":[{"os-family":"bds"},{"os-name":"mac_os_x","release":"17.*"}],"attributes":[],"groups":[{"id":"controls/example.rb","controls":["(generated from example.rb:7 871cd54043069c5c4f6e382fd5627830)","tmp-1.0","(generated from example.rb:21 2ff474c5357e7070f4c3efa932032dcb)"],"title":"sample section"},{"id":"controls/run_command.rb","controls":["(generated from run_command.rb:5 a411d4ded1530b2f48170840e1127584)"]}],"controls":[{"id":"(generated from example.rb:7 871cd54043069c5c4f6e382fd5627830)","title":null,"desc":null,"descriptions":[],"impact":0.5,"refs":[],"tags":{},"code":"","source_location":{"line":89,"ref":"/Users/jquick/Chef/inspec/lib/inspec/control_eval_context.rb"},"waiver_data":{},"results":[{"status":"passed","code_desc":"File /tmp should be directory","run_time":0.002058,"start_time":"2018-01-05 11:43:04 -0500"}]},{"id":"tmp-1.0","title":"Create /tmp directory","desc":"An optional description...","descriptions":[{"label":"default","data":"An optional description..."}],"impact":0.7,"refs":[],"tags":{},"code":"control 'tmp-1.0' do # A unique ID for this control\n impact 0.7 # The criticality, if this control fails.\n title 'Create /tmp directory' # A human-readable title\n desc 'An optional description...'\n describe file('/tmp') do # The actual test\n it { should be_directory }\n end\nend\n","waiver_data":{},"source_location":{"line":12,"ref":"../inspec-demo/_test/long_commands/controls/example.rb"},"results":[{"status":"passed","code_desc":"File /tmp should be directory","run_time":0.000102,"start_time":"2018-01-05 11:43:04 -0500"}]},{"id":"(generated from example.rb:21 2ff474c5357e7070f4c3efa932032dcb)","title":null,"desc":null,"descriptions":[],"impact":0.5,"refs":[],"tags":{},"code":"","waiver_data":{},"source_location":{"line":89,"ref":"/Users/jquick/Chef/inspec/lib/inspec/control_eval_context.rb"},"results":[{"status":"failed","code_desc":"gem package rubocop should be installed","run_time":0.000168,"start_time":"2018-01-05 11:43:04 -0500","message":"rubocop is not installed"}]},{"id":"(generated from run_command.rb:5 a411d4ded1530b2f48170840e1127584)","title":null,"desc":null,"descriptions":[],"impact":0.5,"refs":[],"tags":{},"code":"","waiver_data":{},"source_location":{"line":89,"ref":"/Users/jquick/Chef/inspec/lib/inspec/control_eval_context.rb"},"results":[{"status":"passed","code_desc":"Command whoami stdout should eq \"jquick\\n\"","run_time":0.034938,"start_time":"2018-01-05 11:43:04 -0500"}]}]}],"statistics":{"duration":0.039182},"version":"1.49.2"}
{"platform":{"name":"mac_os_x","release":"17.2.0"},"profiles":[{"name":"long_commands","version":"0.1.0","sha256":"4f816f8cf18f165f05f1cf20936aaad06a15287de3f578891197647ca05c7df4","title":"InSpec Profile","maintainer":"The Authors","summary":"An InSpec Compliance Profile","license":"Apache-2.0","copyright":"The Authors","copyright_email":"you@example.com","supports":[{"os-family":"bds"},{"os-name":"mac_os_x","release":"17.*"}],"attributes":[],"groups":[{"id":"controls/example.rb","controls":["(generated from example.rb:7 871cd54043069c5c4f6e382fd5627830)","tmp-1.0","(generated from example.rb:21 2ff474c5357e7070f4c3efa932032dcb)"],"title":"sample section"},{"id":"controls/run_command.rb","controls":["(generated from run_command.rb:5 a411d4ded1530b2f48170840e1127584)"]}],"controls":[{"id":"(generated from example.rb:7 871cd54043069c5c4f6e382fd5627830)","title":null,"desc":null,"descriptions":[],"impact":0.5,"refs":[],"tags":{},"code":"","source_location":{"line":89,"ref":"/Users/jquick/Chef/inspec/lib/inspec/control_eval_context.rb"},"waiver_data":{},"results":[{"status":"passed","code_desc":"File /tmp should be directory","run_time":0.002058,"start_time":"2018-01-05 11:43:04 -0500","resource_params":""}]},{"id":"tmp-1.0","title":"Create /tmp directory","desc":"An optional description...","descriptions":[{"label":"default","data":"An optional description..."}],"impact":0.7,"refs":[],"tags":{},"code":"control 'tmp-1.0' do # A unique ID for this control\n impact 0.7 # The criticality, if this control fails.\n title 'Create /tmp directory' # A human-readable title\n desc 'An optional description...'\n describe file('/tmp') do # The actual test\n it { should be_directory }\n end\nend\n","waiver_data":{},"source_location":{"line":12,"ref":"../inspec-demo/_test/long_commands/controls/example.rb"},"results":[{"status":"passed","code_desc":"File /tmp should be directory","run_time":0.000102,"start_time":"2018-01-05 11:43:04 -0500","resource_params":""}]},{"id":"(generated from example.rb:21 2ff474c5357e7070f4c3efa932032dcb)","title":null,"desc":null,"descriptions":[],"impact":0.5,"refs":[],"tags":{},"code":"","waiver_data":{},"source_location":{"line":89,"ref":"/Users/jquick/Chef/inspec/lib/inspec/control_eval_context.rb"},"results":[{"status":"failed","code_desc":"gem package rubocop should be installed","run_time":0.000168,"start_time":"2018-01-05 11:43:04 -0500","message":"rubocop is not installed","resource_params":""}]},{"id":"(generated from run_command.rb:5 a411d4ded1530b2f48170840e1127584)","title":null,"desc":null,"descriptions":[],"impact":0.5,"refs":[],"tags":{},"code":"","waiver_data":{},"source_location":{"line":89,"ref":"/Users/jquick/Chef/inspec/lib/inspec/control_eval_context.rb"},"results":[{"status":"passed","code_desc":"Command whoami stdout should eq \"jquick\\n\"","run_time":0.034938,"start_time":"2018-01-05 11:43:04 -0500","resource_params":""}]}]}],"statistics":{"duration":0.039182},"version":"1.49.2"}

View file

@ -14,8 +14,8 @@
- "(generated from t.rb:1 0aa70d93be7b0cf41b97a1363bb5e8b8)"
:controls:
- :id: "(generated from t.rb:1 0aa70d93be7b0cf41b97a1363bb5e8b8)"
:title:
:desc:
:title:
:desc:
:descriptions: []
:impact: 0.5
:refs: []
@ -30,6 +30,7 @@
:code_desc: File /tmp should exist
:run_time: 0.001313935
:start_time: '2018-05-31T16:22:19+05:30'
:resource_params: ''
:statistics:
:duration: 0.002678506
:version: 2.1.83

View file

@ -187,6 +187,29 @@ describe "inspec exec with json formatter" do
_(ex1["impact"]).must_equal 0.7
end
describe "results" do
let(:result) { ex1["results"][0] }
let(:result2) { ex2["results"][0] }
it "has a code_desc" do
_(result["code_desc"]).must_equal "File / is expected to be directory"
end
it "has a resource_class" do
_(result["resource_class"]).must_equal "file"
end
# This is a raw grep of the argument(s) passed to the resource, currently
# used by automate to identify and sort differing resources
it "has a resource_params that's empty" do
_(result["resource_params"]).must_equal "[\"/\"]"
end
it "has a resource_params with values" do
_(result2["resource_params"]).must_equal "[\"/\"]"
end
end
it "has all the metadata" do
actual = profile.dup
key = actual.delete("controls")

View file

@ -15,7 +15,6 @@ describe Inspec::Reporters::JsonAutomate do
report.render
actual = JSON.parse(report.rendered_output, symbolize_names: true)
_(actual).must_equal output
end
end

View file

@ -55,6 +55,7 @@ describe Inspec::Reporters::Json do
code_desc: "File /tmp should be directory",
run_time: 0.002058,
start_time: "2018-01-05 11:43:04 -0500",
resource_params: "",
}
result = report.send(:profile_results, control)
_(result.first).must_equal hash
@ -68,6 +69,7 @@ describe Inspec::Reporters::Json do
code_desc: "File /tmp should be directory",
run_time: 0.002058,
start_time: "2018-01-05 11:43:04 -0500",
resource_params: "",
resource: "File",
skip_message: "skipping",
}