Merge pull request #4577 from inspec/mj/batsignal

Goodbye Gordon!
This commit is contained in:
Miah Johnson 2019-10-17 12:38:53 -07:00 committed by GitHub
commit e634ae495b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 237 additions and 235 deletions

View file

@ -340,10 +340,10 @@ $ inspec shell
Welcome to the interactive InSpec Shell
To find out how to use it, type: help
inspec> command('ls /home/gordon/git/inspec/docs').stdout
=> "ctl_inspec.rst\ndsl_inspec.rst\ndsl_resource.rst\n"
inspec> command('ls').stdout.split("\n")
=> ["ctl_inspec.rst", "dsl_inspec.rst", "dsl_resource.rst"]
inspec> command('ls ~/projects/github/inspec/docs').stdout
=> "README.md\nconfig.md\ndev\ndsl_inspec.md\ndsl_resource.md\nglossary.md\nhabitat.md\ninputs.md\ninspec_and_friends.md\nmatchers.md\nmigration.md\nplatforms.md\nplugin_kitchen_inspec.md\nplugins.md\nprofiles.md\nreporters.md\nresources\nshared\nshell.md\nstyle.md\nwaivers.md\n"
inspec> command('ls ~/projects/github/inspec/docs').stdout.split("\n").first
=> "README.md"
inspec> help command
Name: command

View file

@ -17,7 +17,7 @@ $ tree examples/profile
examples/profile
...
├── libraries
│   └── gordon_config.rb
│   └── example_config.rb
```
## Resource structure
@ -51,8 +51,8 @@ The following example shows a full resource using attributes and methods
to provide simple access to a configuration file:
```ruby
class GordonConfig < Inspec.resource(1)
name 'gordon_config'
class ExampleConfig < Inspec.resource(1)
name 'example_config'
# Restrict to only run on the below platforms (if none were given, all OS's supported)
supports platform_family: 'fedora'
@ -65,14 +65,14 @@ class GordonConfig < Inspec.resource(1)
'
example '
describe gordon_config do
describe example_config do
its("signal") { should eq "on" }
end
'
# Load the configuration file on initialization
def initialize(path = nil)
@path = path || '/etc/gordon.conf'
@path = path || '/etc/example.conf'
@params = SimpleConfig.new( read_content )
end
@ -90,11 +90,11 @@ class GordonConfig < Inspec.resource(1)
# Retrieve the file's contents
f.content
else
# If the file doesn't exist, skip all tests that use gordon_config
# If the file doesn't exist, skip all tests that use example_config
raise Inspec::Exceptions::ResourceSkipped, "Can't read config at #{@path}"
end
end
end
```
For a full example, see our [example resource](https://github.com/chef/inspec/blob/master/examples/profile/libraries/gordon_config.rb).
For a full example, see our [example resource](https://github.com/chef/inspec/blob/master/examples/profile/libraries/example_config.rb).

View file

@ -54,7 +54,7 @@ The following examples show how to use this Chef InSpec audit resource.
end
describe ssh_config do
its('SendEnv') { should include('GORDON_CLIENT') }
its('SendEnv') { should include('CI_ENABLE_COVERAGE') }
end
### Test SSH configuration

View file

@ -42,7 +42,7 @@ The following examples show how to use this Chef InSpec audit resource.
### Test which variables may be sent to the server
describe sshd_config do
its('AcceptEnv') { should include('GORDON_SERVER') }
its('AcceptEnv') { should include('CI_ENABLE_COVERAGE') }
end
### Test for IPv6-only addresses

View file

@ -48,9 +48,9 @@ $ inspec shell -t docker://container_id # Login to a Docker container.
Use resource packs to share custom resources with other Chef InSpec users.
A resource pack is an Chef InSpec profile that contains only custom resources and no other controls or tests.
For example, the profile in [`examples/profile`](https://github.com/chef/inspec/tree/master/examples/profile)in the Chef InSpec git repo defines a [`gordon_config` resource](https://github.com/chef/inspec/blob/master/examples/profile/controls/gordon.rb). To use these resources within the Chef InSpec shell, you will need to download and specify them as a dependency.
For example, the profile in [`examples/profile`](https://github.com/chef/inspec/tree/master/examples/profile)in the Chef InSpec git repo defines a [`example_config` resource](https://github.com/chef/inspec/blob/master/examples/profile/controls/example.rb). To use these resources within the Chef InSpec shell, you will need to download and specify them as a dependency.
Once you have local access to the profile, you can use the `gordon_config` custom resource provided in the `examples/profile` GitHub repo in your local environment :
Once you have local access to the profile, you can use the `example_config` custom resource provided in the `examples/profile` GitHub repo in your local environment :
```bash
inspec shell --depends examples/profile
@ -59,7 +59,7 @@ inspec shell --depends examples/profile
Once inside the shell your resource will be available:
```ruby
inspec> gordon_config
inspec> example_config
```
## Using Ruby in Chef InSpec shell

View file

@ -1,5 +1,4 @@
describe gordon do
its('crime_rate') { should be < 5 }
describe example do
its('crime_rate') { should be < 2 }
it { should have_a_fabulous_mustache }
end

View file

@ -1,21 +1,17 @@
class Gordon < Inspec.resource(1)
name 'gordon'
class Example < Inspec.resource(1)
name "example"
example "
describe gordon do
describe example do
its('crime_rate') { should be < 2 }
it { should have_a_fabulous_mustache }
end
"
def crime_rate
# call out ot another custom resource
inspec.batsignal.number_of_sightings
1
end
def has_a_fabulous_mustache?
# always true
true
end
end

View file

@ -30,8 +30,8 @@ Version: 1.0.0
Target: local://
gordon-1.0: Verify the version number of Gordon (1 skipped)
○ Can't find file "/tmp/gordon/config.yaml"
example-1.0: Verify the version number of Example (1 skipped)
○ Can't find file "/tmp/example/config.yaml"
✔ File content should match nil
✔ ssh-1: Allow only SSH Protocol 2
✔ File /bin/sh should be owned by "root"

View file

@ -4,7 +4,7 @@
include_controls 'profile' do
skip_control 'tmp-1.0'
control 'gordon-1.0' do
control 'example-1.0' do
impact 0.0
end
end

View file

@ -0,0 +1,23 @@
# copyright: 2015, Chef Software, Inc.
title '/tmp profile'
# you add controls here
control "tmp-1.0" do # A unique ID for this control
impact 0.7 # The criticality, if this control fails.
title "Create /tmp directory" # A human-readable title
desc "An optional description..." # Describe why this is needed
desc "label", "An optional description with a label" # Pair a part of the description with a label
tag data: "temp data" # A tag allows you to associate key information
tag "security" # to the test
ref "Document A-12", url: 'http://...' # Additional references
describe file('/tmp') do # The actual test
it { should be_directory }
end
end
# you can also use plain tests
describe file('/tmp') do
it { should be_directory }
end

View file

@ -1,23 +1,35 @@
# copyright: 2015, Chef Software, Inc.
# copyright: 2016, Chef Software, Inc.
title '/tmp profile'
title 'Example Config Checks'
# you add controls here
control "tmp-1.0" do # A unique ID for this control
impact 0.7 # The criticality, if this control fails.
title "Create /tmp directory" # A human-readable title
desc "An optional description..." # Describe why this is needed
desc "label", "An optional description with a label" # Pair a part of the description with a label
tag data: "temp data" # A tag allows you to associate key information
tag "security" # to the test
ref "Document A-12", url: 'http://...' # Additional references
# To pass the test, create the following file
# ```bash
# mkdir -p /tmp/example
# cat <<EOF > /tmp/example/config.yaml
# version: '1.0'
# EOF
# ```
control 'example-1.0' do
impact 'critical'
title 'Verify the version number of Example'
desc 'An optional description...'
tag 'example'
ref 'Example Requirements 1.0', uri: 'http://...'
describe file('/tmp') do # The actual test
it { should be_directory }
# Test using the custom example_config InSpec resource
# Find the resource content here: ../libraries/
describe example_config do
it { should exist }
its('version') { should eq('1.0') }
its('file_size') { should <= 20 }
its('comma_count') { should eq 0 }
end
# Test the version again to showcase variables
g = example_config
g_path = g.file_path
g_version = g.version
describe file(g_path) do
its('content') { should match g_version }
end
end
# you can also use plain tests
describe file('/tmp') do
it { should be_directory }
end

View file

@ -1,35 +0,0 @@
# copyright: 2016, Chef Software, Inc.
title 'Gordon Config Checks'
# To pass the test, create the following file
# ```bash
# mkdir -p /tmp/gordon
# cat <<EOF > /tmp/gordon/config.yaml
# version: '1.0'
# EOF
# ```
control 'gordon-1.0' do
impact 'critical'
title 'Verify the version number of Gordon'
desc 'An optional description...'
tag 'gordon'
ref 'Gordon Requirements 1.0', uri: 'http://...'
# Test using the custom gordon_config InSpec resource
# Find the resource content here: ../libraries/
describe gordon_config do
it { should exist }
its('version') { should eq('1.0') }
its('file_size') { should <= 20 }
its('comma_count') { should eq 0 }
end
# Test the version again to showcase variables
g = gordon_config
g_path = g.file_path
g_version = g.version
describe file(g_path) do
its('content') { should match g_version }
end
end

View file

@ -1,18 +1,18 @@
require "yaml"
# Custom resource based on the InSpec resource DSL
class GordonConfig < Inspec.resource(1)
name "gordon_config"
class ExampleConfig < Inspec.resource(1)
name "example_config"
supports platform: "unix"
supports platform: "windows"
desc "
Gordon's resource description ...
Example's resource description ...
"
example "
describe gordon_config do
describe example_config do
its('version') { should eq('1.0') }
its('file_size') { should > 1 }
end
@ -21,7 +21,7 @@ class GordonConfig < Inspec.resource(1)
# Load the configuration file on initialization
def initialize
@params = {}
@path = "/tmp/gordon/config.yaml"
@path = "/tmp/example/config.yaml"
@file = inspec.file(@path)
unless @file.file?

View file

@ -152,7 +152,7 @@ $ inspec exec compliance://admin/profile
Pending: (Failures listed here are expected and do not affect your suite's status)
1) gordon_config Can't find file "/tmp/gordon/config.yaml"
1) example_config Can't find file "/tmp/example/config.yaml"
# Not yet implemented
# ./lib/inspec/runner.rb:157

View file

@ -84,7 +84,7 @@ module FunctionalHelper
let(:example_profile) { File.join(examples_path, "profile") }
let(:meta_profile) { File.join(examples_path, "meta-profile") }
let(:example_control) { File.join(example_profile, "controls", "example.rb") }
let(:example_control) { File.join(example_profile, "controls", "example-tmp.rb") }
let(:inheritance_profile) { File.join(examples_path, "inheritance") }
let(:failure_control) { File.join(profile_path, "failures", "controls", "failures.rb") }
let(:simple_inheritance) { File.join(profile_path, "simple-inheritance") }
@ -206,8 +206,14 @@ module FunctionalHelper
if opts[:json]
begin
run_result.payload.json = JSON.parse(run_result.stdout)
payload = JSON.parse(run_result.stdout)
run_result.payload.json = payload
rescue JSON::ParserError => e
warn "JSON PARSE ERROR: %s" % [e.message]
warn "OUT: <<%s>>" % [run_result.stdout]
warn "ERR: <<%s>>" % [run_result.stderr]
warn "XIT: %p" % [run_result.exit_status]
run_result.payload.json = {}
run_result.payload.json_error = e
end

View file

@ -32,6 +32,8 @@ describe "inspec exec with json formatter" do
it "can execute a simple file while using end of options after reporter cli option" do
out = inspec("exec --no-create-lockfile --reporter json -- " + example_control)
data = JSON.parse(out.stdout)
sout = Inspec::Schema.json("exec-json")
schema = JSON.parse(sout)
_(JSON::Validator.validate(schema, data)).wont_equal false
_(out.stderr).must_equal ""
@ -115,14 +117,15 @@ describe "inspec exec with json formatter" do
end
describe "execute a profile with json formatting" do
let(:json) { JSON.load(inspec("exec " + example_profile + " --reporter json --no-create-lockfile").stdout) }
let(:raw) { inspec("exec " + example_profile + " --reporter json --no-create-lockfile").stdout }
let(:json) { JSON.load(raw) }
let(:profile) { json["profiles"][0] }
let(:controls) { profile["controls"] }
let(:ex1) { controls.find { |x| x["id"] == "tmp-1.0" } }
let(:ex2) { controls.find { |x| x["id"] =~ /generated/ } }
let(:ex3) { profile["controls"].find { |x| x["id"] == "gordon-1.0" } }
let(:ex3) { profile["controls"].find { |x| x["id"] == "example-1.0" } }
let(:check_result) do
ex3["results"].find { |x| x["resource"] == "gordon_config" }
ex3["results"].find { |x| x["resource"] == "example_config" }
end
it "has only one profile" do
@ -137,8 +140,9 @@ describe "inspec exec with json formatter" do
it "has all the metadata" do
actual = profile.dup
key = actual.delete("controls")
.find { |x| x["id"] =~ /generated from example.rb/ }["id"]
.find { |x| x["id"] =~ /generated from example/ }["id"]
groups = actual.delete("groups")
actual.delete("sha256")
_(actual).must_equal({
"name" => "profile",
"title" => "InSpec Example Profile",
@ -148,16 +152,14 @@ describe "inspec exec with json formatter" do
"license" => "Apache-2.0",
"summary" => "Demonstrates the use of InSpec Compliance Profile",
"version" => "1.0.0",
# TODO: this is brittle and nonsensical
"sha256" => "de67a044d7be7090982740755ff582af1cefaf37261c5adda57b9502ffefc973",
"supports" => [{ "platform-family" => "unix" }, { "platform-family" => "windows" }],
"status" => "loaded",
"attributes" => [],
})
_(groups.sort_by { |x| x["id"] }).must_equal([
{ "id" => "controls/example.rb", "title" => "/tmp profile", "controls" => ["tmp-1.0", key] },
{ "id" => "controls/gordon.rb", "title" => "Gordon Config Checks", "controls" => ["gordon-1.0"] },
{ "id" => "controls/example-tmp.rb", "title" => "/tmp profile", "controls" => ["tmp-1.0", key] },
{ "id" => "controls/example.rb", "title" => "Example Config Checks", "controls" => ["example-1.0"] },
{ "id" => "controls/meta.rb", "title" => "SSH Server Configuration", "controls" => ["ssh-1"] },
])
end
@ -180,7 +182,7 @@ describe "inspec exec with json formatter" do
actual = ex1.dup
src = actual.delete("source_location")
_(src["ref"]).must_match %r{test/unit/mock/profiles/old-examples/profile/controls/example.rb$}
_(src["ref"]).must_match %r{test/unit/mock/profiles/old-examples/profile/controls/example-tmp.rb$}
_(src["line"]).must_equal 6
result = actual.delete("results")[0]

View file

@ -47,7 +47,7 @@ describe "inspec exec" do
let(:controls) { json["controls"] }
let(:ex1) { controls.find { |x| x["id"] == "tmp-1.0" } }
let(:ex2) { controls.find { |x| x["id"] =~ /generated/ } }
let(:ex3) { controls.find { |x| x["id"] == "gordon-1.0" } }
let(:ex3) { controls.find { |x| x["id"] == "example-1.0" } }
it "must have 5 examples" do
_(json["controls"].length).must_equal 5
@ -74,7 +74,7 @@ describe "inspec exec" do
it "has a skip_message" do
_(ex1["skip_message"]).must_be :nil?
_(ex3["skip_message"]).must_equal "Can't find file `/tmp/gordon/config.yaml`"
_(ex3["skip_message"]).must_equal "Can't find file `/tmp/example/config.yaml`"
end
end

View file

@ -59,19 +59,19 @@ describe "inspec exec with junit formatter" do
_(REXML::XPath.match(suite, "//testcase[@name='File /tmp should be directory']").length).must_equal 2
end
describe 'the testcase named "gordon_config Can\'t find file ..."' do
let(:gordon_yml_tests) { REXML::XPath.match(suite, "//testcase[@classname='profile.gordon-1.0' and @name='gordon_config']") }
let(:first_gordon_test) { gordon_yml_tests.first }
describe 'the testcase named "example_config Can\'t find file ..."' do
let(:example_yml_tests) { REXML::XPath.match(suite, "//testcase[@classname='profile.example-1.0' and @name='example_config']") }
let(:first_example_test) { example_yml_tests.first }
it "should be unique" do
_(gordon_yml_tests.length).must_equal 1
_(example_yml_tests.length).must_equal 1
end
it "should be skipped" do
if is_windows?
_(first_gordon_test.elements.to_a("//skipped").length).must_equal 2
_(first_example_test.elements.to_a("//skipped").length).must_equal 2
else
_(first_gordon_test.elements.to_a("//skipped").length).must_equal 1
_(first_example_test.elements.to_a("//skipped").length).must_equal 1
end
end
end

View file

@ -38,8 +38,8 @@ describe "inspec exec" do
_(stdout).must_include "\e[38;5;41m ✔ tmp-1.0: Create /tmp directory\e[0m\n"
_(stdout).must_include "
\e[38;5;247m gordon-1.0: Verify the version number of Gordon (1 skipped)\e[0m
\e[38;5;247m Can't find file `/tmp/gordon/config.yaml`\e[0m
\e[38;5;247m example-1.0: Verify the version number of Example (1 skipped)\e[0m
\e[38;5;247m Can't find file `/tmp/example/config.yaml`\e[0m
"
if is_windows?
_(stdout).must_include "\e[38;5;247m ↺ ssh-1: Allow only SSH Protocol 2\e[0m\n"
@ -341,7 +341,7 @@ Test Summary: 0 successful, 0 failures, 0 skipped
let(:out) { inspec("exec " + example_control + " --no-create-lockfile") }
it "prints the control results, then the anonymous describe block results" do
_(stdout).must_match(/Profile: tests from .*test.unit.mock.profiles.old-examples.profile.controls.example.rb/)
_(stdout).must_match(/Profile: tests from .*test.unit.mock.profiles.old-examples.profile.controls.example-tmp.rb/)
_(stdout).must_include "
Version: (not specified)
Target: local://

View file

@ -73,7 +73,7 @@ describe "inspec json" do
end
it "has a source location" do
loc = File.join(example_profile, "/controls/example.rb")
loc = File.join(example_profile, "/controls/example-tmp.rb")
_(control["source_location"]["ref"]).must_equal loc
_(control["source_location"]["line"]).must_equal 6
end
@ -98,7 +98,7 @@ describe "inspec json" do
_(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.rb"
_(json["groups"][0]["id"]).must_equal "controls/example-tmp.rb"
end
end

View file

@ -19,9 +19,9 @@ describe "inspec shell tests" do
end
it "loads a dependency" do
res = inspec("shell -c 'gordon_config' --depends #{example_profile}")
res = inspec("shell -c 'example_config' --depends #{example_profile}")
_(res.stdout.chop).must_equal "gordon_config"
_(res.stdout.chop).must_equal "example_config"
_(res.stderr).must_equal ""
@ -171,10 +171,10 @@ describe "inspec shell tests" do
end
it "loads a dependency" do
cmd = "echo 'gordon_config' | #{exec_inspec} shell --depends #{example_profile}"
cmd = "echo 'example_config' | #{exec_inspec} shell --depends #{example_profile}"
res = CMD.run_command(cmd)
_(res.stdout).must_include "=> gordon_config"
_(res.stdout).must_include "=> example_config"
assert_exit_code 0, res
end

View file

@ -20,7 +20,7 @@ control 'profilea-1' do # A unique ID for this control
end
control 'profilea-2' do
describe gordon_config do
describe example_config do
its('version') { should eq('1.0') }
end
end

View file

@ -14,7 +14,7 @@ control 'profileb-1' do # A unique ID for this control
end
control 'profileb-2' do
describe gordon_config do
describe example_config do
its('version') { should eq('2.0') }
end
end

View file

@ -0,0 +1,15 @@
class ExampleConfig < Inspec.resource(1)
name 'example_config'
desc "Example's resource description ..."
example "
describe example_config do
its('version') { should eq('1.0') }
end
"
def version
"1.0"
end
end

View file

@ -1,15 +0,0 @@
class GordonConfig < Inspec.resource(1)
name 'gordon_config'
desc "Gordon's resource description ..."
example "
describe gordon_config do
its('version') { should eq('1.0') }
end
"
def version
"1.0"
end
end

View file

@ -0,0 +1,15 @@
class ExampleConfig < Inspec.resource(1)
name 'example_config'
desc "Example's resource description ..."
example "
describe example_config do
its('version') { should eq('2.0') }
end
"
def version
"2.0"
end
end

View file

@ -1,15 +0,0 @@
class GordonConfig < Inspec.resource(1)
name 'gordon_config'
desc "Gordon's resource description ..."
example "
describe gordon_config do
its('version') { should eq('2.0') }
end
"
def version
"2.0"
end
end

View file

@ -1,26 +1,26 @@
# copyright: 2015, The Authors
require_resource(profile: 'profile_c', resource: 'gordon_config', as: 'gordy_config')
require_resource(profile: 'profile_c', resource: 'example_config', as: 'placeholder_config')
describe gordy_config do
describe placeholder_config do
its('version') { should eq('1.0') }
end
control 'whichgordon' do
describe gordy_config do
control 'whichexample' do
describe placeholder_config do
its('version') { should eq('1.0') }
end
describe gordon_config do
describe example_config do
its('version') { should eq('2.0') }
end
describe gordy_config do
its('version') { should eq(gordy_config.version) }
describe placeholder_config do
its('version') { should eq(placeholder_config.version) }
end
describe gordon_config do
its('version') { should eq(gordon_config.version) }
describe example_config do
its('version') { should eq(example_config.version) }
end
end

View file

@ -1,5 +1,5 @@
# copyright: 2015, Chef Software, Inc
describe gordon do
describe example do
it { should be_enabled }
end

View file

@ -0,0 +1,2 @@
module ExampleLib
end

View file

@ -1,2 +0,0 @@
module GordonLib
end

View file

@ -1,11 +1,11 @@
# Library resource
require 'gordonlib'
require 'examplelib'
require 'hashie'
class Gordon < Inspec.resource(1)
name 'gordon'
include GordonLib
class Example < Inspec.resource(1)
name 'example'
include ExampleLib
def enabled?
true
end

View file

@ -1,5 +1,4 @@
describe gordon do
its('crime_rate') { should be < 5 }
describe example do
its('crime_rate') { should be < 2 }
it { should have_a_fabulous_mustache }
end

View file

@ -3,7 +3,7 @@ class Batsignal < Inspec.resource(1)
example "
describe batsignal do
its('number_of_sightings)') { should eq '4' }
its('number_of_sightings)') { should eq '1' }
end
"
@ -15,6 +15,6 @@ class Batsignal < Inspec.resource(1)
def local_command_call
# call out to a core resource
inspec.command('echo 4').stdout.to_i
inspec.command('echo 1').stdout.to_i
end
end

View file

@ -1,8 +1,8 @@
class Gordon < Inspec.resource(1)
name "gordon"
class Example < Inspec.resource(1)
name 'example'
example "
describe gordon do
describe example do
its('crime_rate') { should be < 2 }
it { should have_a_fabulous_mustache }
end

View file

@ -30,8 +30,8 @@ Version: 1.0.0
Target: local://
gordon-1.0: Verify the version number of Gordon (1 skipped)
○ Can't find file "/tmp/gordon/config.yaml"
example-1.0: Verify the version number of Example (1 skipped)
○ Can't find file "/tmp/example/config.yaml"
✔ File content should match nil
✔ ssh-1: Allow only SSH Protocol 2
✔ File /bin/sh should be owned by "root"

View file

@ -4,7 +4,7 @@
include_controls 'profile' do
skip_control 'tmp-1.0'
control 'gordon-1.0' do
control 'example-1.0' do
impact 0.0
end
end

View file

@ -0,0 +1,23 @@
# copyright: 2015, Chef Software, Inc.
title '/tmp profile'
# you add controls here
control 'tmp-1.0' do # A unique ID for this control
impact 0.7 # The criticality, if this control fails.
title 'Create /tmp directory' # A human-readable title
desc 'An optional description...' # Describe why this is needed
desc 'label', 'An optional description with a label' # Pair a part of the description with a label
tag data: 'temp data' # A tag allows you to associate key information
tag 'security' # to the test
ref 'Document A-12', url: 'http://...' # Additional references
describe file('/tmp') do # The actual test
it { should be_directory }
end
end
# you can also use plain tests
describe file('/tmp') do
it { should be_directory }
end

View file

@ -1,23 +1,35 @@
# copyright: 2015, Chef Software, Inc.
# copyright: 2016, Chef Software, Inc.
title '/tmp profile'
title 'Example Config Checks'
# you add controls here
control 'tmp-1.0' do # A unique ID for this control
impact 0.7 # The criticality, if this control fails.
title 'Create /tmp directory' # A human-readable title
desc 'An optional description...' # Describe why this is needed
desc 'label', 'An optional description with a label' # Pair a part of the description with a label
tag data: 'temp data' # A tag allows you to associate key information
tag 'security' # to the test
ref 'Document A-12', url: 'http://...' # Additional references
# To pass the test, create the following file
# ```bash
# mkdir -p /tmp/example
# cat <<EOF > /tmp/example/config.yaml
# version: '1.0'
# EOF
# ```
control 'example-1.0' do
impact 'critical'
title 'Verify the version number of Example'
desc 'An optional description...'
tag 'example'
ref 'Example Requirements 1.0', uri: 'http://...'
describe file('/tmp') do # The actual test
it { should be_directory }
# Test using the custom example_config InSpec resource
# Find the resource content here: ../libraries/
describe example_config do
it { should exist }
its('version') { should eq('1.0') }
its('file_size') { should <= 20 }
its('comma_count') { should eq 0 }
end
# Test the version again to showcase variables
g = example_config
g_path = g.file_path
g_version = g.version
describe file(g_path) do
its('content') { should match g_version }
end
end
# you can also use plain tests
describe file('/tmp') do
it { should be_directory }
end

View file

@ -1,35 +0,0 @@
# copyright: 2016, Chef Software, Inc.
title 'Gordon Config Checks'
# To pass the test, create the following file
# ```bash
# mkdir -p /tmp/gordon
# cat <<EOF > /tmp/gordon/config.yaml
# version: '1.0'
# EOF
# ```
control 'gordon-1.0' do
impact 'critical'
title 'Verify the version number of Gordon'
desc 'An optional description...'
tag 'gordon'
ref 'Gordon Requirements 1.0', uri: 'http://...'
# Test using the custom gordon_config InSpec resource
# Find the resource content here: ../libraries/
describe gordon_config do
it { should exist }
its('version') { should eq('1.0') }
its('file_size') { should <= 20 }
its('comma_count') { should eq 0 }
end
# Test the version again to showcase variables
g = gordon_config
g_path = g.file_path
g_version = g.version
describe file(g_path) do
its('content') { should match g_version }
end
end

View file

@ -1,18 +1,18 @@
require 'yaml'
# Custom resource based on the InSpec resource DSL
class GordonConfig < Inspec.resource(1)
name 'gordon_config'
class ExampleConfig < Inspec.resource(1)
name 'example_config'
supports platform: 'unix'
supports platform: 'windows'
desc "
Gordon's resource description ...
Example's resource description ...
"
example "
describe gordon_config do
describe example_config do
its('version') { should eq('1.0') }
its('file_size') { should > 1 }
end
@ -21,7 +21,7 @@ class GordonConfig < Inspec.resource(1)
# Load the configuration file on initialization
def initialize
@params = {}
@path = '/tmp/gordon/config.yaml'
@path = '/tmp/example/config.yaml'
@file = inspec.file(@path)
unless @file.file?