inspec/test/functional/inspec_json_profile_test.rb
Sonu Saha b5fcc141d2
CHEF-6437: Implement different version of inspec export (#6816)
* Failing test for export - should not evaluate

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* Sketch out a info_from_parse method

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* Temporary commit to checkpoint experimental work

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* Basic control ids extraction

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* Modify to capture entire block

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* Ability to parse desc, impact and title of a control (#6662)

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Rework per-control metadata collectors to be class-based

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* REFACTOR: make a common base class for collectors

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* memoise `info_from_parse`

Signed-off-by: Sathish <sbabu@progress.com>

* Add --legacy-export option to inspec export (#6661)

* support legacy export option

Signed-off-by: Sathish <sbabu@progress.com>

* ability to run legacy export option

Signed-off-by: Sathish <sbabu@progress.com>

---------

Signed-off-by: Sathish <sbabu@progress.com>

* Improve ControlIDCollector and other fields of export data (#6686)

* Parse tags & refs from the ast nodes

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* ENHANCE: Improve Desc collector to collect description

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* ENHANCE: Only loop through the child node of begin block

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* FIX: Fix bug/todo to handle duplicacy of control ids

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* TEST - a profile which fails to properly be exported but is likely to be used by MITRE

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* Revert "FIX: Fix bug/todo to handle duplicacy of control ids"

This reverts commit 46d66e0026.

* Revert "ENHANCE: Only loop through the child node of begin block"

This reverts commit 47c92d8746.

* ADD: Add code key in control data

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* ADD: Add source_location key in controls data

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* HACK: Update the location ref for the controls

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* FIX: Update variable name as latest changes

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* FIX: Fix source location ref for all controls in a file

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* FIX: Improve tagcollector to handle other data types

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* FIX: Improve tagcollector to handle different types of tags

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* ENHANCE & TEST: Improve tag collector to collector different tag styles and add test for it

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* update groups

Signed-off-by: Sathish <sbabu@progress.com>

* Add yml data to export info_from_parse

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Add inputs to export data info_from_parse

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Add status and status_messages

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Initialize all control fields

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* WIP: Filter controls using --controls

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Add inputs collector class - rules remaining

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Parse inputs from dsl - 1

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* TEST: Uncomment tests to verify export

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* TEST: Include test for different desc

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* TEST: Include test for different title

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* TEST: Include test for different ref

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Default impact to 0.5 and add test

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* FIX: Avoid duplicate inputs

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Add test for inputs

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* REFACTOR: Minor refactoring of tests

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Uncomment test for refs

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

---------

Signed-off-by: Sonu Saha <sonu.saha@progress.com>
Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
Signed-off-by: Sathish <sbabu@progress.com>
Co-authored-by: Clinton Wolfe <clintoncwolfe@gmail.com>
Co-authored-by: Sathish <sbabu@progress.com>

* Update option to match inspec's coding standard

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Handle inputs within control block

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* TEST & ENHANCE: Enhance parser and add more tests

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* FIX: Fix broken test for profile_test

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Update groups after filtering control

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Add --legacy-export support to inspec json

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* TEST: Fix broken test & fix group filters

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* DOCS: Manually update cli.md to include export cmd

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Add tag filtering support to export

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* TEST: Add test for tag and control based filtering

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* LINT: Fix lint offense

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* CHORE: Remove addressed todo and update comments

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* CHEF-6493: Support `--legacy-export` option in `inspec archive` (#6829)

* Introduce --legacy-export flag to archive command

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Add more test to verify --legacy-export with archive

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Update logic to fetch info based on --legacy-export flag

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

---------

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Enhance InputCollector to match pattern instead of to indexing children type to avoid nil errors

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Improve RefCollector to handle ref   ({:ref=>'Some ref', :url=>'https://'\}\) syntax

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Improve RefCollector and TagCollector to handle variables values from inputs/attributes

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Run inspec check using output info_from_parse (#6673)

* Add test fixture profile that emits evaluation markers on stderr

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* Failing test for export - should not evaluate

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* Sketch out a info_from_parse method

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* Temporary commit to checkpoint experimental work

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* Basic control ids extraction

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* Modify to capture entire block

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* Ability to parse desc, impact and title of a control (#6662)

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Rework per-control metadata collectors to be class-based

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* REFACTOR: make a common base class for collectors

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* memoise `info_from_parse`

Signed-off-by: Sathish <sbabu@progress.com>

* Add --legacy-export option to inspec export (#6661)

* support legacy export option

Signed-off-by: Sathish <sbabu@progress.com>

* ability to run legacy export option

Signed-off-by: Sathish <sbabu@progress.com>

---------

Signed-off-by: Sathish <sbabu@progress.com>

* Parse tags & refs from the ast nodes

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* ENHANCE: Improve Desc collector to collect description

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* ENHANCE: Only loop through the child node of begin block

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* FIX: Fix bug/todo to handle duplicacy of control ids

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* TEST - a profile which fails to properly be exported but is likely to be used by MITRE

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

* Revert "FIX: Fix bug/todo to handle duplicacy of control ids"

This reverts commit 46d66e0026.

* Revert "ENHANCE: Only loop through the child node of begin block"

This reverts commit 47c92d8746.

* ADD: Add code key in control data

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* ADD: Add source_location key in controls data

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* HACK: Update the location ref for the controls

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* FIX: Update variable name as latest changes

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* FIX: Fix source location ref for all controls in a file

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* FIX: Improve tagcollector to handle other data types

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* FIX: Improve tagcollector to handle different types of tags

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* ENHANCE & TEST: Improve tag collector to collector different tag styles and add test for it

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* update groups

Signed-off-by: Sathish <sbabu@progress.com>

* Add yml data to export info_from_parse

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Add inputs to export data info_from_parse

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Add status and status_messages

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* Initialize all control fields

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* make description `default` as a symbol

Signed-off-by: Sathish Babu <sbabu@progress.com>

* define `checks` as Set

Signed-off-by: Sathish Babu <sbabu@progress.com>

* Collect tests as part of collector
and store it in `checks`

Signed-off-by: Sathish Babu <sbabu@progress.com>

* refactor to read `ID` from controls which is an Array now unlike an Hash in `params.controls`

Signed-off-by: Sathish Babu <sbabu@progress.com>

* read yaml params from metadata

Signed-off-by: Sathish Babu <sbabu@progress.com>

* use to Array to simply DS as the o/p ie being converted to JSON

Signed-off-by: Sathish Babu <sbabu@progress.com>

* move old check as legacy check

Signed-off-by: Sathish Babu <sbabu@progress.com>

* support `legacy_check` as an option to run checks in legacy mode

Signed-off-by: Sathish Babu <sbabu@progress.com>

* fix tests to support `legacy_checks`

Signed-off-by: Sathish Babu <sbabu@progress.com>

* update document for check

Signed-off-by: Sathish Babu <sbabu@progress.com>

* Update usage doc for --legaccy-check

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>

---------

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
Signed-off-by: Sonu Saha <sonu.saha@progress.com>
Signed-off-by: Sathish <sbabu@progress.com>
Signed-off-by: Sathish Babu <sbabu@progress.com>
Co-authored-by: Clinton Wolfe <clintoncwolfe@gmail.com>
Co-authored-by: Sonu Saha <98935583+ahasunos@users.noreply.github.com>
Co-authored-by: Sonu Saha <sonu.saha@progress.com>

* LINT: Fix lint offense

Signed-off-by: Sonu Saha <sonu.saha@progress.com>

* do not include tests to controls by default

Signed-off-by: Sathish Babu <sbabu@progress.com>

* generate info with tests for check

Signed-off-by: Sathish Babu <sbabu@progress.com>

---------

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
Signed-off-by: Sonu Saha <sonu.saha@progress.com>
Signed-off-by: Sathish <sbabu@progress.com>
Signed-off-by: Sathish Babu <sbabu@progress.com>
Co-authored-by: Clinton Wolfe <clintoncwolfe@gmail.com>
Co-authored-by: Sathish <sbabu@progress.com>
Co-authored-by: Sathish Babu <80091550+sathish-progress@users.noreply.github.com>
2023-11-07 15:15:45 +05:30

223 lines
6.6 KiB
Ruby

require "functional/helper"
require "mixlib/shellout"
require "json_schemer"
describe "inspec json" do
include FunctionalHelper
parallelize_me!
it "read the profile json" do
out = inspec("json " + example_profile)
_(out.stderr).must_equal ""
assert_exit_code 0, out
s = out.stdout
_(JSON.load(s)).must_be_kind_of Hash
end
describe "json profile data" do
let(:json) { JSON.load(inspec("json " + example_profile).stdout) }
it "has a generator name" do
_(json["generator"]["name"]).must_equal "inspec"
end
it "has a generator inspec version" do
_(json["generator"]["version"]).must_equal Inspec::VERSION
end
it "has empty array of inputs" do
_(json["inputs"]).must_be_empty
end
it "has a name" do
_(json["name"]).must_equal "profile"
end
it "has a title" do
_(json["title"]).must_equal "InSpec Example Profile"
end
it "has a summary" do
_(json["summary"]).must_equal "Demonstrates the use of InSpec Compliance Profile"
end
it "has a version" do
_(json["version"]).must_equal "1.0.0"
end
it "has a maintainer" do
_(json["maintainer"]).must_equal "Chef Software, Inc."
end
it "has a copyright" do
_(json["copyright"]).must_equal "Chef Software, Inc."
end
it "has controls" do
_(json["controls"].length).must_equal 3 # Orphaned describe block (without control as parent) is not considered a control in the new export
end
describe "a control" do
let(:control) { json["controls"].find { |x| x["id"] == "tmp-1.0" } }
it "has a title" do
_(control["title"]).must_equal "Create / directory"
end
it "has a description" do
_(control["desc"]).must_equal "An optional description..."
end
it "has an impact" do
_(control["impact"]).must_equal 0.7
end
it "has a ref" do
_(control["refs"]).must_equal([{ "ref" => "Document A-12", "url" => "http://..." }])
end
it "has a source location" do
loc = File.join(example_profile, "/controls/example-tmp.rb")
_(control["source_location"]["ref"]).must_equal loc
_(control["source_location"]["line"]).must_equal 6
end
it "has a the source code" do
_(control["code"]).must_match(/\Acontrol 'tmp-1.0' do.*end\Z/m) # New export doesn't add a new line at the end
end
end
end
describe "json profile data with inputs" do
let(:json) { JSON.load(inspec("json " + examples_path + "/profile-attribute").stdout) }
it "has a inputs" do
_(json["inputs"]).must_equal [{ "name" => "user", "options" => { "value" => "alice" } }, { "name" => "password", "options" => { "value" => "Input 'password' does not have a value. Skipping test." } }]
end
end
describe "filter with --controls" do
let(:out) { inspec("json " + example_profile + " --controls tmp-1.0") }
it "still succeeds" do
_(out.stderr).must_equal ""
assert_exit_code 0, out
end
it "only has one control included" do
json = JSON.load(out.stdout)
_(json["controls"].length).must_equal 1
_(json["controls"][0]["id"]).must_equal "tmp-1.0"
_(json["groups"].length).must_equal 1
_(json["groups"][0]["id"]).must_equal "controls/example-tmp.rb"
end
end
it "writes json to file" do
out = inspec("json " + example_profile + " --output " + dst.path)
hm = JSON.load(File.read(dst.path))
_(hm["name"]).must_equal "profile"
_(hm["controls"].length).must_equal 3 # Orphaned describe block (without control as parent) is not considered a control in the new export
_(out.stderr).must_include "----> creating #{dst.path}"
assert_exit_code 0, out
end
describe "json test for pax header archives" do
let(:profile_tgz) { File.join(Dir.mktmpdir, "pax-profile-test.tar.gz") }
it "successfully reads a pax-formatted tar file" do
# TODO: this needs updated to also support windows taring
return if is_windows?
files = Dir.glob("#{example_profile}/**/*").delete_if { |x| !File.file?(x) }
relatives = files.map { |e| Pathname.new(e).relative_path_from(Pathname.new(example_profile)).to_s }
cmd = Mixlib::ShellOut.new("tar --format=pax -czf #{profile_tgz} #{relatives.join(" ")}", cwd: example_profile)
cmd.run_command
cmd.error!
out = inspec("json #{profile_tgz}")
assert_exit_code 0, out
end
end
describe "inspec json with a inheritance profile" do
let(:profile) { File.join(profile_path, "export-json", "empty-wrapper") }
it "can export a profile that uses inheritance" do
out = inspec("json " + profile)
# This will throw an exception if it is garbled
json = JSON.load(out.stdout)
# and here we verify (very passingly!) that is a structure we expect
_(json).must_be_kind_of Hash
json["controls"].each do |control|
_(control["code"].empty?).must_equal false
end
_(out.stderr).must_be_empty
assert_exit_code 0, out
end
end
describe "inspec json does not write logs to STDOUT" do
it "can execute a profile with warn calls and parse STDOUT as valid JSON" do
out = inspec("json " + File.join(profile_path, "warn_logs") + " --legacy-export") # Latest export doesn't show the warn calls
assert_equal "warn_logs", JSON.load(out.stdout)["name"]
_(out.stderr).must_include "This is a warn call"
assert_exit_code 0, out
end
end
describe "inspec json with a profile containing only_if" do
it "ignores the `only_if`" do
out = inspec("json " + File.join(profile_path, "only-if-os-nope"))
assert_equal "only-if-os-nope", JSON.load(out.stdout)["name"]
_(out.stderr).must_equal ""
assert_exit_code 0, out
end
end
it "can format a profile and validate the json schema" do
out = inspec("json " + example_profile)
data = JSON.parse(out.stdout)
sout = inspec("schema profile-json")
schema = JSONSchemer.schema(sout.stdout)
_(schema.validate(data).to_a).must_equal []
_(out.stderr).must_equal ""
assert_exit_code 0, out
end
it "properly validates all (valid) unit tests against the schema" do
schema = JSONSchemer.schema(JSON.parse(inspec("schema profile-json").stdout))
all_profile_folders.first(1).each do |folder|
out = inspec("json " + folder)
# Ensure it parses properly; discard the result
out = JSON.parse(out.stdout)
failures = schema.validate(out).to_a
_(failures).must_equal []
rescue JSON::ParserError
# We don't actually care about these; cannot validate if parsing fails!
nil
end
end
end