mirror of
https://github.com/inspec/inspec
synced 2024-11-10 07:04:15 +00:00
Merge branch 'master' into mj/ccp
This commit is contained in:
commit
666a937838
151 changed files with 618 additions and 265 deletions
|
@ -1,5 +1,6 @@
|
||||||
[inspec]
|
[inspec]
|
||||||
build_targets = [
|
build_targets = [
|
||||||
|
"x86_64-windows",
|
||||||
"x86_64-linux",
|
"x86_64-linux",
|
||||||
"x86_64-linux-kernel2"
|
"x86_64-linux-kernel2"
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,3 +28,4 @@ exclude_patterns:
|
||||||
- "www/source/javascripts/"
|
- "www/source/javascripts/"
|
||||||
- "examples/"
|
- "examples/"
|
||||||
- "test/unit/mock/profiles/"
|
- "test/unit/mock/profiles/"
|
||||||
|
- "test/kitchen"
|
20
.expeditor/artifact.habitat.yml
Normal file
20
.expeditor/artifact.habitat.yml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- label: ":linux: Validate Habitat Builds of Chef InSpec"
|
||||||
|
commands:
|
||||||
|
- /workdir/.expeditor/buildkite/artifact.habitat.test.sh
|
||||||
|
expeditor:
|
||||||
|
executor:
|
||||||
|
linux:
|
||||||
|
privileged: true
|
||||||
|
single-use: true
|
||||||
|
|
||||||
|
- label: ":windows: Validate Habitat Builds of Chef InSpec"
|
||||||
|
commands:
|
||||||
|
- /workdir/.expeditor/buildkite/artifact.habitat.test.ps1
|
||||||
|
expeditor:
|
||||||
|
executor:
|
||||||
|
windows:
|
||||||
|
privileged: true
|
||||||
|
single-use: true
|
36
.expeditor/buildkite/artifact.habitat.test.ps1
Normal file
36
.expeditor/buildkite/artifact.habitat.test.ps1
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#!/usr/bin/env powershell
|
||||||
|
|
||||||
|
#Requires -Version 5
|
||||||
|
|
||||||
|
$env:HAB_ORIGIN = 'ci'
|
||||||
|
$Plan = 'inspec'
|
||||||
|
|
||||||
|
Write-Host "--- system details"
|
||||||
|
$Properties = 'Caption', 'CSName', 'Version', 'BuildType', 'OSArchitecture'
|
||||||
|
Get-CimInstance Win32_OperatingSystem | Select-Object $Properties | Format-Table -AutoSize
|
||||||
|
|
||||||
|
Write-Host "--- Installing the version of Habitat required"
|
||||||
|
Install-Habitat --version 0.85.0.20190916
|
||||||
|
|
||||||
|
Write-Host "--- Generating fake origin key"
|
||||||
|
hab origin key generate $env:HAB_ORIGIN
|
||||||
|
|
||||||
|
Write-Host "--- Building $Plan"
|
||||||
|
$project_root = "$(git rev-parse --show-toplevel)"
|
||||||
|
Set-Location $project_root
|
||||||
|
|
||||||
|
$env:DO_CHECK=$true; hab pkg build .
|
||||||
|
if (-not $?) { throw "unable to build" }
|
||||||
|
|
||||||
|
. results/last_build.ps1
|
||||||
|
if (-not $?) { throw "unable to determine details about this build" }
|
||||||
|
|
||||||
|
Write-Host "--- Installing $pkg_ident"
|
||||||
|
hab pkg install results/$pkg_artifact
|
||||||
|
if (-not $?) { throw "unable to install this build" }
|
||||||
|
|
||||||
|
Write-Host "+++ Testing $Plan"
|
||||||
|
Push-Location $project_root/test/artifact
|
||||||
|
rake
|
||||||
|
if (-not $?) { throw "rake failed" }
|
||||||
|
Pop-Location
|
28
.expeditor/buildkite/artifact.habitat.test.sh
Normal file
28
.expeditor/buildkite/artifact.habitat.test.sh
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -ueo pipefail
|
||||||
|
|
||||||
|
export HAB_ORIGIN='ci'
|
||||||
|
export PLAN='inspec'
|
||||||
|
|
||||||
|
echo "--- system details"
|
||||||
|
uname -a
|
||||||
|
|
||||||
|
echo "--- Generating fake origin key"
|
||||||
|
hab origin key generate ${HAB_ORIGIN}
|
||||||
|
|
||||||
|
echo "--- Building $PLAN"
|
||||||
|
project_root="$(git rev-parse --show-toplevel)"
|
||||||
|
cd "$project_root"
|
||||||
|
|
||||||
|
DO_CHECK=true hab pkg build .
|
||||||
|
|
||||||
|
. results/last_build.sh
|
||||||
|
|
||||||
|
echo "--- Installing $pkg_ident"
|
||||||
|
hab pkg install "results/$pkg_artifact"
|
||||||
|
|
||||||
|
echo "+++ Testing $PLAN"
|
||||||
|
pushd "$project_root/test/artifact"
|
||||||
|
rake
|
||||||
|
popd
|
|
@ -33,7 +33,6 @@ pipelines:
|
||||||
- N: 5
|
- N: 5
|
||||||
- coverage:
|
- coverage:
|
||||||
description: Generate test coverage report
|
description: Generate test coverage report
|
||||||
public: true
|
|
||||||
env:
|
env:
|
||||||
- CI_ENABLE_COVERAGE: true
|
- CI_ENABLE_COVERAGE: true
|
||||||
- LANG: "C.UTF-8"
|
- LANG: "C.UTF-8"
|
||||||
|
@ -44,6 +43,9 @@ pipelines:
|
||||||
- www/deploy:
|
- www/deploy:
|
||||||
description: Deploy website to inspec.io
|
description: Deploy website to inspec.io
|
||||||
definition: .expeditor/wwwdeploy.yml
|
definition: .expeditor/wwwdeploy.yml
|
||||||
|
- integration/resources:
|
||||||
|
description: Test core resources with test-kitchen.
|
||||||
|
definition: .expeditor/integration.resources.yml
|
||||||
- integration/libraries:
|
- integration/libraries:
|
||||||
description: Integration with plugins, gems, resource packs.
|
description: Integration with plugins, gems, resource packs.
|
||||||
definition: .expeditor/integration.libraries.yml
|
definition: .expeditor/integration.libraries.yml
|
||||||
|
@ -56,6 +58,9 @@ pipelines:
|
||||||
- integration/automate:
|
- integration/automate:
|
||||||
description: Integration with Chef Automate
|
description: Integration with Chef Automate
|
||||||
definition: .expeditor/integration.automate.yml
|
definition: .expeditor/integration.automate.yml
|
||||||
|
- artifact/habitat:
|
||||||
|
description: Execute tests against the habitat artifact
|
||||||
|
definition: .expeditor/artifact.habitat.yml
|
||||||
|
|
||||||
schedules:
|
schedules:
|
||||||
- name: integration_schedule
|
- name: integration_schedule
|
||||||
|
@ -164,3 +169,4 @@ subscriptions:
|
||||||
only_if_team_member:
|
only_if_team_member:
|
||||||
- inspec/owners
|
- inspec/owners
|
||||||
- inspec/inspec-core-team
|
- inspec/inspec-core-team
|
||||||
|
- post_github_comment:.expeditor/templates/pull_request.mustache
|
||||||
|
|
1
.expeditor/integration.resources.yml
Normal file
1
.expeditor/integration.resources.yml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#
|
|
@ -1,5 +1,6 @@
|
||||||
AllCops:
|
AllCops:
|
||||||
Exclude:
|
Exclude:
|
||||||
|
- 'test/kitchen/**/*'
|
||||||
- 'test/integration/**/controls/**/*.rb'
|
- 'test/integration/**/controls/**/*.rb'
|
||||||
- 'test/unit/mock/profiles/**/*.rb'
|
- 'test/unit/mock/profiles/**/*.rb'
|
||||||
- 'test/unit/mock/config_dirs/**/*.rb'
|
- 'test/unit/mock/config_dirs/**/*.rb'
|
||||||
|
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,16 +1,22 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
<!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ -->
|
<!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ -->
|
||||||
<!-- latest_release 4.18.2 -->
|
<!-- latest_release 4.18.6 -->
|
||||||
## [v4.18.2](https://github.com/inspec/inspec/tree/v4.18.2) (2019-10-15)
|
## [v4.18.6](https://github.com/inspec/inspec/tree/v4.18.6) (2019-10-18)
|
||||||
|
|
||||||
#### Merged Pull Requests
|
#### Merged Pull Requests
|
||||||
- Telemetry: add chef-core [#4569](https://github.com/inspec/inspec/pull/4569) ([clintoncwolfe](https://github.com/clintoncwolfe))
|
- Refactored and added an alternative test mock resource system. [#4566](https://github.com/inspec/inspec/pull/4566) ([zenspider](https://github.com/zenspider))
|
||||||
<!-- latest_release -->
|
<!-- latest_release -->
|
||||||
|
|
||||||
<!-- release_rollup since=4.18.0 -->
|
<!-- release_rollup since=4.18.0 -->
|
||||||
### Changes since 4.18.0 release
|
### Changes since 4.18.0 release
|
||||||
|
|
||||||
#### Merged Pull Requests
|
#### Merged Pull Requests
|
||||||
|
- Refactored and added an alternative test mock resource system. [#4566](https://github.com/inspec/inspec/pull/4566) ([zenspider](https://github.com/zenspider)) <!-- 4.18.6 -->
|
||||||
|
- Use a good profile with inspec check test [#4612](https://github.com/inspec/inspec/pull/4612) ([miah](https://github.com/miah)) <!-- 4.18.5 -->
|
||||||
|
- Dont trigger yet [#4611](https://github.com/inspec/inspec/pull/4611) ([miah](https://github.com/miah)) <!-- 4.18.4 -->
|
||||||
|
- Empty resources yml until I build it. [#4610](https://github.com/inspec/inspec/pull/4610) ([miah](https://github.com/miah)) <!-- 4.18.4 -->
|
||||||
|
- Re-organize test-kitchen files. Add BK Pipeline [#4601](https://github.com/inspec/inspec/pull/4601) ([miah](https://github.com/miah)) <!-- 4.18.4 -->
|
||||||
|
- Goodbye Gordon! [#4577](https://github.com/inspec/inspec/pull/4577) ([miah](https://github.com/miah)) <!-- 4.18.3 -->
|
||||||
- Telemetry: add chef-core [#4569](https://github.com/inspec/inspec/pull/4569) ([clintoncwolfe](https://github.com/clintoncwolfe)) <!-- 4.18.2 -->
|
- Telemetry: add chef-core [#4569](https://github.com/inspec/inspec/pull/4569) ([clintoncwolfe](https://github.com/clintoncwolfe)) <!-- 4.18.2 -->
|
||||||
|
|
||||||
#### Bug Fixes
|
#### Bug Fixes
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
4.18.2
|
4.18.6
|
|
@ -340,10 +340,10 @@ $ inspec shell
|
||||||
Welcome to the interactive InSpec Shell
|
Welcome to the interactive InSpec Shell
|
||||||
To find out how to use it, type: help
|
To find out how to use it, type: help
|
||||||
|
|
||||||
inspec> command('ls /home/gordon/git/inspec/docs').stdout
|
inspec> command('ls ~/projects/github/inspec/docs').stdout
|
||||||
=> "ctl_inspec.rst\ndsl_inspec.rst\ndsl_resource.rst\n"
|
=> "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').stdout.split("\n")
|
inspec> command('ls ~/projects/github/inspec/docs').stdout.split("\n").first
|
||||||
=> ["ctl_inspec.rst", "dsl_inspec.rst", "dsl_resource.rst"]
|
=> "README.md"
|
||||||
|
|
||||||
inspec> help command
|
inspec> help command
|
||||||
Name: command
|
Name: command
|
||||||
|
|
|
@ -17,7 +17,7 @@ $ tree examples/profile
|
||||||
examples/profile
|
examples/profile
|
||||||
...
|
...
|
||||||
├── libraries
|
├── libraries
|
||||||
│ └── gordon_config.rb
|
│ └── example_config.rb
|
||||||
```
|
```
|
||||||
|
|
||||||
## Resource structure
|
## 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:
|
to provide simple access to a configuration file:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
class GordonConfig < Inspec.resource(1)
|
class ExampleConfig < Inspec.resource(1)
|
||||||
name 'gordon_config'
|
name 'example_config'
|
||||||
|
|
||||||
# Restrict to only run on the below platforms (if none were given, all OS's supported)
|
# Restrict to only run on the below platforms (if none were given, all OS's supported)
|
||||||
supports platform_family: 'fedora'
|
supports platform_family: 'fedora'
|
||||||
|
@ -65,14 +65,14 @@ class GordonConfig < Inspec.resource(1)
|
||||||
'
|
'
|
||||||
|
|
||||||
example '
|
example '
|
||||||
describe gordon_config do
|
describe example_config do
|
||||||
its("signal") { should eq "on" }
|
its("signal") { should eq "on" }
|
||||||
end
|
end
|
||||||
'
|
'
|
||||||
|
|
||||||
# Load the configuration file on initialization
|
# Load the configuration file on initialization
|
||||||
def initialize(path = nil)
|
def initialize(path = nil)
|
||||||
@path = path || '/etc/gordon.conf'
|
@path = path || '/etc/example.conf'
|
||||||
@params = SimpleConfig.new( read_content )
|
@params = SimpleConfig.new( read_content )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -90,11 +90,11 @@ class GordonConfig < Inspec.resource(1)
|
||||||
# Retrieve the file's contents
|
# Retrieve the file's contents
|
||||||
f.content
|
f.content
|
||||||
else
|
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}"
|
raise Inspec::Exceptions::ResourceSkipped, "Can't read config at #{@path}"
|
||||||
end
|
end
|
||||||
end
|
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).
|
||||||
|
|
|
@ -54,7 +54,7 @@ The following examples show how to use this Chef InSpec audit resource.
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ssh_config do
|
describe ssh_config do
|
||||||
its('SendEnv') { should include('GORDON_CLIENT') }
|
its('SendEnv') { should include('CI_ENABLE_COVERAGE') }
|
||||||
end
|
end
|
||||||
|
|
||||||
### Test SSH configuration
|
### Test SSH configuration
|
||||||
|
|
|
@ -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
|
### Test which variables may be sent to the server
|
||||||
|
|
||||||
describe sshd_config do
|
describe sshd_config do
|
||||||
its('AcceptEnv') { should include('GORDON_SERVER') }
|
its('AcceptEnv') { should include('CI_ENABLE_COVERAGE') }
|
||||||
end
|
end
|
||||||
|
|
||||||
### Test for IPv6-only addresses
|
### Test for IPv6-only addresses
|
||||||
|
|
|
@ -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.
|
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.
|
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
|
```bash
|
||||||
inspec shell --depends examples/profile
|
inspec shell --depends examples/profile
|
||||||
|
@ -59,7 +59,7 @@ inspec shell --depends examples/profile
|
||||||
Once inside the shell your resource will be available:
|
Once inside the shell your resource will be available:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
inspec> gordon_config
|
inspec> example_config
|
||||||
```
|
```
|
||||||
|
|
||||||
## Using Ruby in Chef InSpec shell
|
## Using Ruby in Chef InSpec shell
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
describe gordon do
|
describe example do
|
||||||
its('crime_rate') { should be < 5 }
|
its('crime_rate') { should be < 2 }
|
||||||
it { should have_a_fabulous_mustache }
|
it { should have_a_fabulous_mustache }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,17 @@
|
||||||
class Gordon < Inspec.resource(1)
|
class Example < Inspec.resource(1)
|
||||||
name 'gordon'
|
name "example"
|
||||||
|
|
||||||
example "
|
example "
|
||||||
describe gordon do
|
describe example do
|
||||||
its('crime_rate') { should be < 2 }
|
its('crime_rate') { should be < 2 }
|
||||||
it { should have_a_fabulous_mustache }
|
it { should have_a_fabulous_mustache }
|
||||||
end
|
end
|
||||||
"
|
"
|
||||||
|
|
||||||
def crime_rate
|
def crime_rate
|
||||||
# call out ot another custom resource
|
1
|
||||||
inspec.batsignal.number_of_sightings
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_a_fabulous_mustache?
|
def has_a_fabulous_mustache?
|
||||||
# always true
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,8 +30,8 @@ Version: 1.0.0
|
||||||
Target: local://
|
Target: local://
|
||||||
|
|
||||||
|
|
||||||
○ gordon-1.0: Verify the version number of Gordon (1 skipped)
|
○ example-1.0: Verify the version number of Example (1 skipped)
|
||||||
○ Can't find file "/tmp/gordon/config.yaml"
|
○ Can't find file "/tmp/example/config.yaml"
|
||||||
✔ File content should match nil
|
✔ File content should match nil
|
||||||
✔ ssh-1: Allow only SSH Protocol 2
|
✔ ssh-1: Allow only SSH Protocol 2
|
||||||
✔ File /bin/sh should be owned by "root"
|
✔ File /bin/sh should be owned by "root"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
include_controls 'profile' do
|
include_controls 'profile' do
|
||||||
skip_control 'tmp-1.0'
|
skip_control 'tmp-1.0'
|
||||||
|
|
||||||
control 'gordon-1.0' do
|
control 'example-1.0' do
|
||||||
impact 0.0
|
impact 0.0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
23
examples/profile/controls/example-tmp.rb
Normal file
23
examples/profile/controls/example-tmp.rb
Normal 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
|
|
@ -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
|
# To pass the test, create the following file
|
||||||
control "tmp-1.0" do # A unique ID for this control
|
# ```bash
|
||||||
impact 0.7 # The criticality, if this control fails.
|
# mkdir -p /tmp/example
|
||||||
title "Create /tmp directory" # A human-readable title
|
# cat <<EOF > /tmp/example/config.yaml
|
||||||
desc "An optional description..." # Describe why this is needed
|
# version: '1.0'
|
||||||
desc "label", "An optional description with a label" # Pair a part of the description with a label
|
# EOF
|
||||||
tag data: "temp data" # A tag allows you to associate key information
|
# ```
|
||||||
tag "security" # to the test
|
control 'example-1.0' do
|
||||||
ref "Document A-12", url: 'http://...' # Additional references
|
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
|
# Test using the custom example_config InSpec resource
|
||||||
it { should be_directory }
|
# 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
|
||||||
end
|
end
|
||||||
|
|
||||||
# you can also use plain tests
|
|
||||||
describe file('/tmp') do
|
|
||||||
it { should be_directory }
|
|
||||||
end
|
|
||||||
|
|
|
@ -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
|
|
|
@ -1,18 +1,18 @@
|
||||||
require "yaml"
|
require "yaml"
|
||||||
|
|
||||||
# Custom resource based on the InSpec resource DSL
|
# Custom resource based on the InSpec resource DSL
|
||||||
class GordonConfig < Inspec.resource(1)
|
class ExampleConfig < Inspec.resource(1)
|
||||||
name "gordon_config"
|
name "example_config"
|
||||||
|
|
||||||
supports platform: "unix"
|
supports platform: "unix"
|
||||||
supports platform: "windows"
|
supports platform: "windows"
|
||||||
|
|
||||||
desc "
|
desc "
|
||||||
Gordon's resource description ...
|
Example's resource description ...
|
||||||
"
|
"
|
||||||
|
|
||||||
example "
|
example "
|
||||||
describe gordon_config do
|
describe example_config do
|
||||||
its('version') { should eq('1.0') }
|
its('version') { should eq('1.0') }
|
||||||
its('file_size') { should > 1 }
|
its('file_size') { should > 1 }
|
||||||
end
|
end
|
||||||
|
@ -21,7 +21,7 @@ class GordonConfig < Inspec.resource(1)
|
||||||
# Load the configuration file on initialization
|
# Load the configuration file on initialization
|
||||||
def initialize
|
def initialize
|
||||||
@params = {}
|
@params = {}
|
||||||
@path = "/tmp/gordon/config.yaml"
|
@path = "/tmp/example/config.yaml"
|
||||||
@file = inspec.file(@path)
|
@file = inspec.file(@path)
|
||||||
|
|
||||||
unless @file.file?
|
unless @file.file?
|
85
habitat/plan.ps1
Normal file
85
habitat/plan.ps1
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
$pkg_name="inspec"
|
||||||
|
$pkg_origin="chef"
|
||||||
|
$pkg_version=$(Get-Content "$PLAN_CONTEXT/../VERSION")
|
||||||
|
$pkg_revision="1"
|
||||||
|
$pkg_description="InSpec is an open-source testing framework for infrastructure
|
||||||
|
with a human- and machine-readable language for specifying compliance,
|
||||||
|
security and policy requirements."
|
||||||
|
$pkg_upstream_url="https://www.inspec.io/"
|
||||||
|
$pkg_maintainer="The Chef Maintainers <humans@chef.io>"
|
||||||
|
$pkg_license=('Apache-2.0')
|
||||||
|
|
||||||
|
$pkg_deps=@(
|
||||||
|
"core/cacerts"
|
||||||
|
"robbkidd/ruby-plus-devkit"
|
||||||
|
)
|
||||||
|
$pkg_bin_dirs=@("bin"
|
||||||
|
"vendor/bin")
|
||||||
|
$project_root= (Resolve-Path "$PLAN_CONTEXT/../").Path
|
||||||
|
|
||||||
|
function Invoke-SetupEnvironment {
|
||||||
|
Push-RuntimeEnv -IsPath GEM_PATH "$pkg_prefix/vendor"
|
||||||
|
|
||||||
|
Set-RuntimeEnv APPBUNDLER_ALLOW_RVM "true" # prevent appbundler from clearing out the carefully constructed runtime GEM_PATH
|
||||||
|
Set-RuntimeEnv -IsPath SSL_CERT_FILE "$(Get-HabPackagePath cacerts)/ssl/cert.pem"
|
||||||
|
Set-RuntimeEnv LANG "en_US.UTF-8"
|
||||||
|
Set-RuntimeEnv LC_CTYPE "en_US.UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Invoke-Build {
|
||||||
|
try {
|
||||||
|
Push-Location $project_root
|
||||||
|
$env:GEM_HOME = "$HAB_CACHE_SRC_PATH/$pkg_dirname/vendor"
|
||||||
|
|
||||||
|
Write-BuildLine " ** Configuring bundler for this build environment"
|
||||||
|
bundle config --local without integration deploy maintenance
|
||||||
|
bundle config --local jobs 4
|
||||||
|
|
||||||
|
Write-BuildLine " ** Using bundler to retrieve the Ruby dependencies"
|
||||||
|
bundle install
|
||||||
|
Write-BuildLine " ** Running the inspec project's 'rake install' to install the path-based gems so they look like any other installed gem."
|
||||||
|
bundle exec rake install # this needs to be 'bundle exec'd because a Rakefile makes reference to Bundler
|
||||||
|
} finally {
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Invoke-Install {
|
||||||
|
Write-BuildLine "** Copy built & cached gems to install directory"
|
||||||
|
Copy-Item -Path "$HAB_CACHE_SRC_PATH/$pkg_dirname/*" -Destination $pkg_prefix -Recurse -Force -Exclude @("gem_make.out", "mkmf.log", "Makefile")
|
||||||
|
|
||||||
|
try {
|
||||||
|
Push-Location $pkg_prefix
|
||||||
|
bundle config --local gemfile $project_root/Gemfile
|
||||||
|
foreach($gem in ("inspec-bin", "inspec")) {
|
||||||
|
Write-BuildLine "** generating binstubs for $gem with precise version pins"
|
||||||
|
Invoke-Expression -Command "appbundler.bat $project_root $pkg_prefix/bin $gem"
|
||||||
|
}
|
||||||
|
Remove-StudioPathFrom -File $pkg_prefix/vendor/gems/inspec-$pkg_version*/Gemfile
|
||||||
|
} finally {
|
||||||
|
Pop-Location
|
||||||
|
# forget about the build bundle config
|
||||||
|
Remove-Item $pkg_prefix/.bundle -Recurse -Force
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Invoke-After {
|
||||||
|
# We don't need the cache of downloaded .gem files ...
|
||||||
|
Remove-Item $pkg_prefix/vendor/cache -Recurse -Force
|
||||||
|
# We don't need the gem docs.
|
||||||
|
Remove-Item $pkg_prefix/vendor/doc -Recurse -Force
|
||||||
|
# We don't need to ship the test suites for every gem dependency,
|
||||||
|
# only inspec's for package verification.
|
||||||
|
Get-ChildItem $pkg_prefix/vendor/gems -Filter "spec" -Directory -Recurse -Depth 1 `
|
||||||
|
| Where-Object -FilterScript { $_.FullName -notlike "*inspec*" } `
|
||||||
|
| Remove-Item -Recurse -Force
|
||||||
|
}
|
||||||
|
|
||||||
|
function Remove-StudioPathFrom {
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[String]
|
||||||
|
$File
|
||||||
|
)
|
||||||
|
(Get-Content $File) -replace ($env:FS_ROOT -replace "\\","/"),"" | Set-Content $File
|
||||||
|
}
|
10
inspec-bin/Rakefile
Normal file
10
inspec-bin/Rakefile
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Bundler::GemHelper.install_tasks(name: "inspec-bin")
|
||||||
|
|
||||||
|
desc "force install the inspec-bin gem"
|
||||||
|
task "install:force" do
|
||||||
|
sh "gem build -V inspec-bin.gemspec"
|
||||||
|
built_gem_path = Dir["inspec-bin-*.gem"].sort_by { |f| File.mtime(f) }.last
|
||||||
|
FileUtils.mkdir_p("pkg") unless Dir.exist?("pkg")
|
||||||
|
FileUtils.mv(built_gem_path, "pkg")
|
||||||
|
sh "gem install -f pkg/#{built_gem_path}"
|
||||||
|
end
|
|
@ -1,5 +1,5 @@
|
||||||
# This file managed by automation - do not edit manually
|
# This file managed by automation - do not edit manually
|
||||||
module InspecBin
|
module InspecBin
|
||||||
INSPECBIN_ROOT = File.expand_path("../..", __FILE__)
|
INSPECBIN_ROOT = File.expand_path("../..", __FILE__)
|
||||||
VERSION = "4.18.2".freeze
|
VERSION = "4.18.6".freeze
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,7 @@ verifier:
|
||||||
|
|
||||||
lifecycle:
|
lifecycle:
|
||||||
pre_converge:
|
pre_converge:
|
||||||
- local: gem build inspec-core.gemspec --output test/cookbooks/os_prepare/files/inspec-core-local.gem
|
- local: gem build inspec-core.gemspec --output test/kitchen/cookbooks/os_prepare/files/inspec-core-local.gem
|
||||||
|
|
||||||
platforms:
|
platforms:
|
||||||
# The following (private) boxes are shared via VagrantCloud and are only
|
# The following (private) boxes are shared via VagrantCloud and are only
|
||||||
|
|
|
@ -11,7 +11,7 @@ verifier:
|
||||||
|
|
||||||
lifecycle:
|
lifecycle:
|
||||||
pre_converge:
|
pre_converge:
|
||||||
- local: gem build inspec-core.gemspec --output test/cookbooks/os_prepare/files/inspec-core-local.gem
|
- local: gem build inspec-core.gemspec --output test/kitchen/cookbooks/os_prepare/files/inspec-core-local.gem
|
||||||
|
|
||||||
platforms:
|
platforms:
|
||||||
- name: centos-6
|
- name: centos-6
|
||||||
|
@ -35,6 +35,6 @@ suites:
|
||||||
- recipe[os_prepare::find_files]
|
- recipe[os_prepare::find_files]
|
||||||
verifier:
|
verifier:
|
||||||
inspec_tests:
|
inspec_tests:
|
||||||
- test/integration/find_files
|
- test/kitchen/policies/find_files
|
||||||
excludes:
|
excludes:
|
||||||
- freebsd-11
|
- freebsd-11
|
||||||
|
|
10
kitchen.yml
10
kitchen.yml
|
@ -9,7 +9,7 @@ transport:
|
||||||
|
|
||||||
lifecycle:
|
lifecycle:
|
||||||
pre_converge:
|
pre_converge:
|
||||||
- local: gem build inspec-core.gemspec --output test/cookbooks/os_prepare/files/inspec-core-local.gem
|
- local: gem build inspec-core.gemspec --output test/kitchen/cookbooks/os_prepare/files/inspec-core-local.gem
|
||||||
|
|
||||||
provisioner:
|
provisioner:
|
||||||
name: dokken
|
name: dokken
|
||||||
|
@ -100,13 +100,13 @@ platforms:
|
||||||
- RUN /usr/bin/apt-get update -y
|
- RUN /usr/bin/apt-get update -y
|
||||||
|
|
||||||
suites:
|
suites:
|
||||||
- name: default
|
- name: resources-core
|
||||||
run_list:
|
run_list:
|
||||||
- recipe[os_prepare]
|
- recipe[os_prepare]
|
||||||
- recipe[audit]
|
- recipe[audit]
|
||||||
verifier:
|
verifier:
|
||||||
inspec_tests:
|
inspec_tests:
|
||||||
- test/integration/default
|
- test/kitchen/policies/resources-core
|
||||||
attributes:
|
attributes:
|
||||||
audit:
|
audit:
|
||||||
attributes:
|
attributes:
|
||||||
|
@ -122,3 +122,7 @@ suites:
|
||||||
osprepare:
|
osprepare:
|
||||||
docker: true
|
docker: true
|
||||||
application: false
|
application: false
|
||||||
|
|
||||||
|
- name: resources-database
|
||||||
|
- name: resources-unix
|
||||||
|
- name: resources-windows
|
||||||
|
|
|
@ -70,6 +70,9 @@ module Inspec::Resources
|
||||||
repo[repo_key(strip(val[1]))] = strip(val[2])
|
repo[repo_key(strip(val[1]))] = strip(val[2])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@cache.push(repo) if in_repo
|
||||||
|
|
||||||
@cache
|
@cache
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
module Inspec
|
module Inspec
|
||||||
VERSION = "4.18.2".freeze
|
VERSION = "4.18.6".freeze
|
||||||
end
|
end
|
||||||
|
|
|
@ -152,7 +152,7 @@ $ inspec exec compliance://admin/profile
|
||||||
|
|
||||||
Pending: (Failures listed here are expected and do not affect your suite's status)
|
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
|
# Not yet implemented
|
||||||
# ./lib/inspec/runner.rb:157
|
# ./lib/inspec/runner.rb:157
|
||||||
|
|
||||||
|
|
5
test/artifact/README.md
Normal file
5
test/artifact/README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# InSpec Artifact test suite
|
||||||
|
|
||||||
|
A minimal set of tests to validate functionality after 'build'.
|
||||||
|
|
||||||
|
Execute this after building InSpec artifacts with omnibus, habitat, or another system.
|
7
test/artifact/Rakefile
Normal file
7
test/artifact/Rakefile
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
require "rake/testtask"
|
||||||
|
|
||||||
|
Rake::TestTask.new(:test) do |t|
|
||||||
|
t.test_files = FileList["*_test.rb"].sort
|
||||||
|
end
|
||||||
|
|
||||||
|
task default: :test
|
12
test/artifact/inspec_detect_test.rb
Normal file
12
test/artifact/inspec_detect_test.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
require "minitest/autorun"
|
||||||
|
|
||||||
|
class TestArtifactDetect < Minitest::Test
|
||||||
|
def test_detect
|
||||||
|
out, err = capture_subprocess_io do
|
||||||
|
assert system("inspec detect --no-color")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_match %r{/Platform Details/}, out
|
||||||
|
assert_empty err
|
||||||
|
end
|
||||||
|
end
|
|
@ -80,11 +80,9 @@ module FunctionalHelper
|
||||||
let(:mock_path) { File.join(repo_path, "test", "unit", "mock") }
|
let(:mock_path) { File.join(repo_path, "test", "unit", "mock") }
|
||||||
let(:profile_path) { File.join(mock_path, "profiles") }
|
let(:profile_path) { File.join(mock_path, "profiles") }
|
||||||
let(:examples_path) { File.join(profile_path, "old-examples") }
|
let(:examples_path) { File.join(profile_path, "old-examples") }
|
||||||
let(:integration_test_path) { File.join(repo_path, "test", "integration", "default") }
|
|
||||||
|
|
||||||
let(:example_profile) { File.join(examples_path, "profile") }
|
let(:example_profile) { File.join(examples_path, "profile") }
|
||||||
let(:meta_profile) { File.join(examples_path, "meta-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(:inheritance_profile) { File.join(examples_path, "inheritance") }
|
||||||
let(:failure_control) { File.join(profile_path, "failures", "controls", "failures.rb") }
|
let(:failure_control) { File.join(profile_path, "failures", "controls", "failures.rb") }
|
||||||
let(:simple_inheritance) { File.join(profile_path, "simple-inheritance") }
|
let(:simple_inheritance) { File.join(profile_path, "simple-inheritance") }
|
||||||
|
@ -206,8 +204,14 @@ module FunctionalHelper
|
||||||
|
|
||||||
if opts[:json]
|
if opts[:json]
|
||||||
begin
|
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
|
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 = {}
|
||||||
run_result.payload.json_error = e
|
run_result.payload.json_error = e
|
||||||
end
|
end
|
||||||
|
|
|
@ -60,8 +60,8 @@ describe "inspec check" do
|
||||||
Dir.mktmpdir do |tmpdir|
|
Dir.mktmpdir do |tmpdir|
|
||||||
cache_dir = File.join(tmpdir, "inspec_check_test_cache")
|
cache_dir = File.join(tmpdir, "inspec_check_test_cache")
|
||||||
_(File.exist?(cache_dir)).must_equal false
|
_(File.exist?(cache_dir)).must_equal false
|
||||||
|
good_profile_path = File.join(repo_path, "test/unit/mock/profiles/complete-profile")
|
||||||
out = inspec("check " + integration_test_path + " --vendor-cache " + cache_dir)
|
out = inspec("check #{good_profile_path} --vendor-cache #{cache_dir}")
|
||||||
|
|
||||||
_(File.exist?(cache_dir)).must_equal true
|
_(File.exist?(cache_dir)).must_equal true
|
||||||
assert_exit_code 0, out
|
assert_exit_code 0, out
|
||||||
|
|
|
@ -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
|
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)
|
out = inspec("exec --no-create-lockfile --reporter json -- " + example_control)
|
||||||
data = JSON.parse(out.stdout)
|
data = JSON.parse(out.stdout)
|
||||||
|
sout = Inspec::Schema.json("exec-json")
|
||||||
|
schema = JSON.parse(sout)
|
||||||
_(JSON::Validator.validate(schema, data)).wont_equal false
|
_(JSON::Validator.validate(schema, data)).wont_equal false
|
||||||
|
|
||||||
_(out.stderr).must_equal ""
|
_(out.stderr).must_equal ""
|
||||||
|
@ -115,14 +117,15 @@ describe "inspec exec with json formatter" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "execute a profile with json formatting" do
|
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(:profile) { json["profiles"][0] }
|
||||||
let(:controls) { profile["controls"] }
|
let(:controls) { profile["controls"] }
|
||||||
let(:ex1) { controls.find { |x| x["id"] == "tmp-1.0" } }
|
let(:ex1) { controls.find { |x| x["id"] == "tmp-1.0" } }
|
||||||
let(:ex2) { controls.find { |x| x["id"] =~ /generated/ } }
|
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
|
let(:check_result) do
|
||||||
ex3["results"].find { |x| x["resource"] == "gordon_config" }
|
ex3["results"].find { |x| x["resource"] == "example_config" }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "has only one profile" do
|
it "has only one profile" do
|
||||||
|
@ -137,8 +140,9 @@ describe "inspec exec with json formatter" do
|
||||||
it "has all the metadata" do
|
it "has all the metadata" do
|
||||||
actual = profile.dup
|
actual = profile.dup
|
||||||
key = actual.delete("controls")
|
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")
|
groups = actual.delete("groups")
|
||||||
|
actual.delete("sha256")
|
||||||
_(actual).must_equal({
|
_(actual).must_equal({
|
||||||
"name" => "profile",
|
"name" => "profile",
|
||||||
"title" => "InSpec Example Profile",
|
"title" => "InSpec Example Profile",
|
||||||
|
@ -148,16 +152,14 @@ describe "inspec exec with json formatter" do
|
||||||
"license" => "Apache-2.0",
|
"license" => "Apache-2.0",
|
||||||
"summary" => "Demonstrates the use of InSpec Compliance Profile",
|
"summary" => "Demonstrates the use of InSpec Compliance Profile",
|
||||||
"version" => "1.0.0",
|
"version" => "1.0.0",
|
||||||
# TODO: this is brittle and nonsensical
|
|
||||||
"sha256" => "de67a044d7be7090982740755ff582af1cefaf37261c5adda57b9502ffefc973",
|
|
||||||
"supports" => [{ "platform-family" => "unix" }, { "platform-family" => "windows" }],
|
"supports" => [{ "platform-family" => "unix" }, { "platform-family" => "windows" }],
|
||||||
"status" => "loaded",
|
"status" => "loaded",
|
||||||
"attributes" => [],
|
"attributes" => [],
|
||||||
})
|
})
|
||||||
|
|
||||||
_(groups.sort_by { |x| x["id"] }).must_equal([
|
_(groups.sort_by { |x| x["id"] }).must_equal([
|
||||||
{ "id" => "controls/example.rb", "title" => "/tmp profile", "controls" => ["tmp-1.0", key] },
|
{ "id" => "controls/example-tmp.rb", "title" => "/tmp profile", "controls" => ["tmp-1.0", key] },
|
||||||
{ "id" => "controls/gordon.rb", "title" => "Gordon Config Checks", "controls" => ["gordon-1.0"] },
|
{ "id" => "controls/example.rb", "title" => "Example Config Checks", "controls" => ["example-1.0"] },
|
||||||
{ "id" => "controls/meta.rb", "title" => "SSH Server Configuration", "controls" => ["ssh-1"] },
|
{ "id" => "controls/meta.rb", "title" => "SSH Server Configuration", "controls" => ["ssh-1"] },
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
@ -180,7 +182,7 @@ describe "inspec exec with json formatter" do
|
||||||
actual = ex1.dup
|
actual = ex1.dup
|
||||||
|
|
||||||
src = actual.delete("source_location")
|
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
|
_(src["line"]).must_equal 6
|
||||||
|
|
||||||
result = actual.delete("results")[0]
|
result = actual.delete("results")[0]
|
||||||
|
|
|
@ -47,7 +47,7 @@ describe "inspec exec" do
|
||||||
let(:controls) { json["controls"] }
|
let(:controls) { json["controls"] }
|
||||||
let(:ex1) { controls.find { |x| x["id"] == "tmp-1.0" } }
|
let(:ex1) { controls.find { |x| x["id"] == "tmp-1.0" } }
|
||||||
let(:ex2) { controls.find { |x| x["id"] =~ /generated/ } }
|
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
|
it "must have 5 examples" do
|
||||||
_(json["controls"].length).must_equal 5
|
_(json["controls"].length).must_equal 5
|
||||||
|
@ -74,7 +74,7 @@ describe "inspec exec" do
|
||||||
|
|
||||||
it "has a skip_message" do
|
it "has a skip_message" do
|
||||||
_(ex1["skip_message"]).must_be :nil?
|
_(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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -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
|
_(REXML::XPath.match(suite, "//testcase[@name='File /tmp should be directory']").length).must_equal 2
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'the testcase named "gordon_config Can\'t find file ..."' do
|
describe 'the testcase named "example_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(:example_yml_tests) { REXML::XPath.match(suite, "//testcase[@classname='profile.example-1.0' and @name='example_config']") }
|
||||||
let(:first_gordon_test) { gordon_yml_tests.first }
|
let(:first_example_test) { example_yml_tests.first }
|
||||||
|
|
||||||
it "should be unique" do
|
it "should be unique" do
|
||||||
_(gordon_yml_tests.length).must_equal 1
|
_(example_yml_tests.length).must_equal 1
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should be skipped" do
|
it "should be skipped" do
|
||||||
if is_windows?
|
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
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -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;41m ✔ tmp-1.0: Create /tmp directory\e[0m\n"
|
||||||
_(stdout).must_include "
|
_(stdout).must_include "
|
||||||
\e[38;5;247m ↺ gordon-1.0: Verify the version number of Gordon (1 skipped)\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/gordon/config.yaml`\e[0m
|
\e[38;5;247m ↺ Can't find file `/tmp/example/config.yaml`\e[0m
|
||||||
"
|
"
|
||||||
if is_windows?
|
if is_windows?
|
||||||
_(stdout).must_include "\e[38;5;247m ↺ ssh-1: Allow only SSH Protocol 2\e[0m\n"
|
_(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") }
|
let(:out) { inspec("exec " + example_control + " --no-create-lockfile") }
|
||||||
|
|
||||||
it "prints the control results, then the anonymous describe block results" do
|
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 "
|
_(stdout).must_include "
|
||||||
Version: (not specified)
|
Version: (not specified)
|
||||||
Target: local://
|
Target: local://
|
||||||
|
|
|
@ -73,7 +73,7 @@ describe "inspec json" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "has a source location" do
|
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"]["ref"]).must_equal loc
|
||||||
_(control["source_location"]["line"]).must_equal 6
|
_(control["source_location"]["line"]).must_equal 6
|
||||||
end
|
end
|
||||||
|
@ -98,7 +98,7 @@ describe "inspec json" do
|
||||||
_(json["controls"].length).must_equal 1
|
_(json["controls"].length).must_equal 1
|
||||||
_(json["controls"][0]["id"]).must_equal "tmp-1.0"
|
_(json["controls"][0]["id"]).must_equal "tmp-1.0"
|
||||||
_(json["groups"].length).must_equal 1
|
_(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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,9 @@ describe "inspec shell tests" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "loads a dependency" do
|
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 ""
|
_(res.stderr).must_equal ""
|
||||||
|
|
||||||
|
@ -171,10 +171,10 @@ describe "inspec shell tests" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "loads a dependency" do
|
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 = CMD.run_command(cmd)
|
||||||
|
|
||||||
_(res.stdout).must_include "=> gordon_config"
|
_(res.stdout).must_include "=> example_config"
|
||||||
|
|
||||||
assert_exit_code 0, res
|
assert_exit_code 0, res
|
||||||
end
|
end
|
||||||
|
|
|
@ -70,6 +70,7 @@ require "mocha/setup"
|
||||||
require "inspec/log"
|
require "inspec/log"
|
||||||
require "inspec/backend"
|
require "inspec/backend"
|
||||||
require "helpers/mock_loader"
|
require "helpers/mock_loader"
|
||||||
|
require "helpers/resources"
|
||||||
|
|
||||||
TMP_CACHE = {} # rubocop: disable Style/MutableConstant
|
TMP_CACHE = {} # rubocop: disable Style/MutableConstant
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
class MockLoader
|
class MockLoader
|
||||||
# collects emulation operating systems
|
# collects emulation operating systems
|
||||||
OPERATING_SYSTEMS = {
|
OPERATING_SYSTEMS = { # rubocop:disable Style/MutableConstant
|
||||||
alpine: { name: "alpine", family: "alpine", release: "3.6.2", arch: "x86_64" },
|
alpine: { name: "alpine", family: "alpine", release: "3.6.2", arch: "x86_64" },
|
||||||
arch: { name: "arch", family: "arch", release: nil, arch: nil },
|
arch: { name: "arch", family: "arch", release: nil, arch: nil },
|
||||||
centos5: { name: "centos", family: "redhat", release: "5.11", arch: "x86_64" },
|
centos5: { name: "centos", family: "redhat", release: "5.11", arch: "x86_64" },
|
||||||
centos6: { name: "centos", family: "redhat", release: "6.6", arch: "x86_64" },
|
centos6: { name: "centos", family: "redhat", release: "6.6", arch: "x86_64" },
|
||||||
centos7: { name: "centos", family: "redhat", release: "7.1.1503", arch: "x86_64" },
|
centos7: { name: "centos", family: "redhat", release: "7.1.1503", arch: "x86_64" },
|
||||||
|
centos8: { name: "centos", family: "redhat", release: "8.9.10", arch: "x86_64" },
|
||||||
cloudlinux: { name: "cloudlinux", family: "redhat", release: "7.4", arch: "x86_64" },
|
cloudlinux: { name: "cloudlinux", family: "redhat", release: "7.4", arch: "x86_64" },
|
||||||
coreos: { name: "coreos", family: "coreos", release: "1437.0.0", arch: "x86_64" },
|
coreos: { name: "coreos", family: "coreos", release: "1437.0.0", arch: "x86_64" },
|
||||||
debian6: { name: "debian", family: "debian", release: "6", arch: "x86_64" },
|
debian6: { name: "debian", family: "debian", release: "6", arch: "x86_64" },
|
||||||
|
@ -30,7 +31,9 @@ class MockLoader
|
||||||
amazon: { name: "amazon", family: "redhat", release: "2015.03", arch: "x86_64" },
|
amazon: { name: "amazon", family: "redhat", release: "2015.03", arch: "x86_64" },
|
||||||
amazon2: { name: "amazon", family: "redhat", release: "2", arch: "x86_64" },
|
amazon2: { name: "amazon", family: "redhat", release: "2", arch: "x86_64" },
|
||||||
undefined: { name: nil, family: nil, release: nil, arch: nil },
|
undefined: { name: nil, family: nil, release: nil, arch: nil },
|
||||||
}.freeze
|
}
|
||||||
|
|
||||||
|
OPERATING_SYSTEMS[:linux] = OPERATING_SYSTEMS[:ubuntu1604]
|
||||||
|
|
||||||
# pass the os identifier to emulate a specific operating system
|
# pass the os identifier to emulate a specific operating system
|
||||||
def initialize(os = :ubuntu1404)
|
def initialize(os = :ubuntu1404)
|
||||||
|
@ -209,7 +212,6 @@ class MockLoader
|
||||||
"Auditpol /get /subcategory:'User Account Management' /r" => cmd.call("auditpol"),
|
"Auditpol /get /subcategory:'User Account Management' /r" => cmd.call("auditpol"),
|
||||||
"/sbin/auditctl -l" => cmd.call("auditctl"),
|
"/sbin/auditctl -l" => cmd.call("auditctl"),
|
||||||
"/sbin/auditctl -s" => cmd.call("auditctl-s"),
|
"/sbin/auditctl -s" => cmd.call("auditctl-s"),
|
||||||
"yum -v repolist all" => cmd.call("yum-repolist-all"),
|
|
||||||
"dpkg -s curl" => cmd.call("dpkg-s-curl"),
|
"dpkg -s curl" => cmd.call("dpkg-s-curl"),
|
||||||
"dpkg -s held-package" => cmd.call("dpkg-s-held-package"),
|
"dpkg -s held-package" => cmd.call("dpkg-s-held-package"),
|
||||||
"rpm -qi curl" => cmd.call("rpm-qi-curl"),
|
"rpm -qi curl" => cmd.call("rpm-qi-curl"),
|
||||||
|
|
58
test/helpers/resources.rb
Normal file
58
test/helpers/resources.rb
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
class Minitest::Test
|
||||||
|
##
|
||||||
|
# This creates a real resource with default config/backend.
|
||||||
|
#
|
||||||
|
# Use this whenever possible. Let's phase out the MockLoader pain.
|
||||||
|
|
||||||
|
def quick_resource(name, platform = :linux, *args, &block)
|
||||||
|
backend = Inspec::Backend.create(Inspec::Config.new)
|
||||||
|
backend.extend Fake::Backend
|
||||||
|
|
||||||
|
os = MockLoader::OPERATING_SYSTEMS[platform]
|
||||||
|
raise "Unknown platform: %p" % [platform] unless os
|
||||||
|
|
||||||
|
# mock.mock_os(@platform)
|
||||||
|
platform = Train::Platforms.name(os[:name])
|
||||||
|
platform.find_family_hierarchy # TODO: remove? UGH! adds platform=
|
||||||
|
platform.platform = os
|
||||||
|
# platform.add_platform_methods # TODO: remove?
|
||||||
|
# TODO: this should have a setter
|
||||||
|
# TODO: backend.backend is the WORST name
|
||||||
|
backend.backend.instance_variable_set :@platform, platform
|
||||||
|
# end mock.mock_os
|
||||||
|
|
||||||
|
klass = Inspec::Resource.registry[name]
|
||||||
|
|
||||||
|
instance = klass.new(backend, name, *args)
|
||||||
|
instance.extend Fake::Resource
|
||||||
|
instance.mock_command(&block) if block
|
||||||
|
instance
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Fake
|
||||||
|
Command = Struct.new(:stdout, :stderr, :exit_status)
|
||||||
|
|
||||||
|
module Backend
|
||||||
|
def stdout_file(path)
|
||||||
|
result(path, nil, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
def stderr_file(path)
|
||||||
|
result(nil, path, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
def result(stdout_path, stderr_path, exit)
|
||||||
|
stdout = stdout_path ? File.read(stdout_path) : ""
|
||||||
|
stderr = stderr_path ? File.read(stderr_path) : ""
|
||||||
|
|
||||||
|
::Fake::Command.new(stdout, stderr, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Resource
|
||||||
|
def mock_command(&block)
|
||||||
|
inspec.define_singleton_method :command, &block
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue