Merge remote-tracking branch 'upstream/main' into add-http-for-windows-2

This commit is contained in:
Mendy Baitelman 2021-08-31 17:08:28 -07:00
commit 7abebdf80b
300 changed files with 5091 additions and 2032 deletions

View file

@ -0,0 +1,51 @@
#!/bin/bash
# Enable IPv6 in docker
echo "--- Enabling ipv6 on docker"
sudo systemctl stop docker
dockerd_config="/etc/docker/daemon.json"
sudo echo "$(jq '. + {"ipv6": true, "fixed-cidr-v6": "2001:2019:6002::/80", "ip-forward": false}' $dockerd_config)" > $dockerd_config
sudo systemctl start docker
# Install C and C++
echo "--- Installing package deps"
sudo yum install -y gcc gcc-c++ openssl-devel readline-devel zlib-devel
# Install ASDF
echo "--- Installing asdf to ${HOME}/.asdf"
git clone https://github.com/asdf-vm/asdf.git "${HOME}/.asdf"
cd "${HOME}/.asdf"; git checkout "$(git describe --abbrev=0 --tags)"; cd -
. "${HOME}/.asdf/asdf.sh"
# Install Ruby
ruby_version=$(sed -n '/"ruby"/{s/.*version: "//;s/"//;p;}' omnibus_overrides.rb)
echo "--- Installing Ruby $ruby_version"
asdf plugin add ruby
asdf install ruby $ruby_version
asdf global ruby $ruby_version
# Set Environment Variables
export BUNDLE_GEMFILE=$PWD/Gemfile
export FORCE_FFI_YAJL=ext
export CHEF_LICENSE="accept-silent"
# Update Gems
echo "--- Installing Gems"
echo 'gem: --no-document' >> ~/.gemrc
sudo iptables -L DOCKER || ( echo "DOCKER iptables chain missing" ; sudo iptables -N DOCKER )
bundle install --jobs=3 --retry=3 --path=../vendor/bundle
echo "--- Config information"
echo "!!!! RUBY VERSION !!!!"
ruby --version
echo "!!!! BUNDLER LOCATION !!!!"
which bundle
echo "!!!! BUNDLER VERSION !!!!"
bundle -v
echo "!!!! DOCKER VERSION !!!!"
docker version
echo "!!!! DOCKER STATUS !!!!"
sudo service docker status
echo "+++ Running tests"

View file

@ -1,70 +0,0 @@
#!/bin/bash
set -ueo pipefail
export LANG=C.UTF-8 LANGUAGE=C.UTF-8
# test-reporter expects reporter identifier under this environment variable
CC_TEST_REPORTER_ID="$COVERAGE_ID"
export CC_TEST_REPORTER_ID
TEST_REPORTER_VERSION="0.6.3"
S3_URL="s3://public-cd-buildkite-cache/$BUILDKITE_PIPELINE_SLUG/$BUILDKITE_LABEL"
download_test_reporter() {
curl -o test-reporter -L https://codeclimate.com/downloads/test-reporter/test-reporter-"$TEST_REPORTER_VERSION"-linux-amd64
chmod +x test-reporter
touch new_test-reporter
}
download_s3_file() {
aws s3 cp "$S3_URL/$1" "$1"
}
upload_s3_file() {
if [ -f "$1" ]; then
aws s3 cp "$1" "$S3_URL/$1" || echo "Could not push $1 to S3 for caching."
fi
}
echo "--- downloading coverage tool"
download_s3_file test-reporter || download_test_reporter
download_s3_file test-reporter.sha || echo -e "\nCould not download test-reporter.sha"
echo "--- updating rubygems"
gem update --system -N
echo "--- system details"
uname -a
gem env
bundle --version
echo "--- setting up test coverage before build"
./test-reporter before-build
echo "--- bundle install"
bundle install --jobs=7 --retry=3 --without tools maintenance deploy
echo "+++ bundle exec rake"
bundle exec rake test
EXIT_CODE=$?
echo "+++ formatting and uploading test coverage"
./test-reporter sum-coverage
./test-reporter after-build -t simplecov --exit-code "$EXIT_CODE"
echo "--- uploading test-reporter.sha to s3"
if [ -f "new_test-reporter" ]; then
echo "new test-reporter detected. uploading."
shasum -a 256 test-reporter > test-reporter.sha
for i in "test-reporter" "test-reporter.sha"; do
upload_s3_file "$i"
done
fi
if shasum --check test-reporter.sha --status; then
echo "test-reporter shasum mismatch. uploading."
shasum -a 256 test-reporter > test-reporter.sha
for i in "test-reporter" "test-reporter.sha"; do
upload_s3_file "$i"
done
fi

View file

@ -31,15 +31,10 @@ pipelines:
- SLOW: 1
- NO_AWS: 1
- MT_CPU: 5
- coverage:
description: Generate test coverage report
env:
- CI_ENABLE_COVERAGE: true
- LANG: "C.UTF-8"
- SLOW: 1
- integration/resources:
description: Test core resources with test-kitchen.
definition: .expeditor/integration.resources.yml
trigger: pull_request
# This breaks expeditor as it does not yet exist
# - integration/libraries:
# description: Integration with plugins, gems, resource packs.
@ -75,8 +70,9 @@ github:
minor_bump_labels:
- "Expeditor: Bump Minor Version"
version_tag_format: v{{version}}
release_branch:
- master:
release_branches:
- main:
version_constraint: 4.*
- 1-stable:
version_constraint: 1.*
@ -95,90 +91,88 @@ changelog:
- "Type: Enhancement": "Enhancements"
- "Type: Bug": "Bug Fixes"
merge_actions:
- built_in:bump_version:
ignore_labels:
- "Expeditor: Skip All"
- "Expeditor: Skip Version Bump"
only_if_modified:
- .expeditor/*
- docs-chef-io/*
- etc/*
- habitat/*
- inspec-bin/*
- lib/*
- omnibus/*
- support/*
- tasks/*
- test/*
- Gemfile*
- LICENSE
- "*.gemspec"
- "*.md"
- bash:.expeditor/update_version.sh:
only_if: built_in:bump_version
- built_in:update_changelog:
ignore_labels:
- "Expeditor: Skip All"
- "Expeditor: Skip Changelog"
- trigger_pipeline:omnibus/adhoc:
not_if: built_in:bump_version
ignore_labels:
- "Expeditor: Skip Omnibus"
- "Expeditor: Skip All"
- trigger_pipeline:artifact/habitat:
only_if: built_in:bump_version
ignore_labels:
- "Expeditor: Skip Habitat"
- "Expeditor: Skip All"
- trigger_pipeline:omnibus/release:
only_if: built_in:bump_version
ignore_labels:
- "Expeditor: Skip Omnibus"
- "Expeditor: Skip All"
- trigger_pipeline:habitat/build:
only_if: built_in:bump_version
ignore_labels:
- "Expeditor: Skip Habitat"
- "Expeditor: Skip All"
- built_in:build_gem:
only_if:
- built_in:bump_version
subscriptions:
- workload: artifact_published:unstable:inspec:{{version_constraint}}
actions:
- trigger_pipeline:docker/build
- bash:.expeditor/buildkite/wwwrelease.sh:
post_commit: true
- workload: artifact_published:current:inspec:{{version_constraint}}
actions:
- built_in:promote_docker_images
- built_in:promote_habitat_packages
- workload: artifact_published:stable:inspec:{{version_constraint}}
actions:
- bash:.expeditor/update_dockerfile.sh
- built_in:rollover_changelog
- built_in:publish_rubygems
- built_in:create_github_release
- built_in:promote_docker_images
- built_in:promote_habitat_packages
- bash:.expeditor/publish-release-notes.sh:
post_commit: true
- purge_packages_chef_io_fastly:{{target_channel}}/inspec/latest:
post_commit: true
- bash:.expeditor/announce-release.sh:
post_commit: true
- built_in:notify_chefio_slack_channels
- workload: pull_request_opened:{{agent_id}}:*
actions:
- post_github_comment:.expeditor/templates/pull_request.mustache:
ignore_team_members:
- inspec/owners
- inspec/inspec-core-team
- built_in:github_auto_assign_author:
only_if_team_member:
- inspec/owners
- inspec/inspec-core-team
- trigger_pipeline:coverage
- trigger_pipeline:artifact/habitat
- workload: pull_request_merged:{{github_repo}}:{{release_branch}}:*
actions:
- built_in:bump_version:
ignore_labels:
- "Expeditor: Skip All"
- "Expeditor: Skip Version Bump"
only_if_modified:
- .expeditor/*
- docs-chef-io/*
- etc/*
- habitat/*
- inspec-bin/*
- lib/*
- omnibus/*
- support/*
- tasks/*
- test/*
- Gemfile*
- LICENSE
- "*.gemspec"
- "*.md"
- bash:.expeditor/update_version.sh:
only_if: built_in:bump_version
- built_in:update_changelog:
ignore_labels:
- "Expeditor: Skip All"
- "Expeditor: Skip Changelog"
- trigger_pipeline:omnibus/adhoc:
not_if: built_in:bump_version
ignore_labels:
- "Expeditor: Skip Omnibus"
- "Expeditor: Skip All"
- trigger_pipeline:artifact/habitat:
only_if: built_in:bump_version
ignore_labels:
- "Expeditor: Skip Habitat"
- "Expeditor: Skip All"
- trigger_pipeline:omnibus/release:
only_if: built_in:bump_version
ignore_labels:
- "Expeditor: Skip Omnibus"
- "Expeditor: Skip All"
- trigger_pipeline:habitat/build:
only_if: built_in:bump_version
ignore_labels:
- "Expeditor: Skip Habitat"
- "Expeditor: Skip All"
- built_in:build_gem:
only_if:
- built_in:bump_version
- workload: artifact_published:unstable:inspec:{{version_constraint}}
actions:
- trigger_pipeline:docker/build
- bash:.expeditor/buildkite/wwwrelease.sh:
post_commit: true
- workload: artifact_published:current:inspec:{{version_constraint}}
actions:
- built_in:promote_docker_images
- built_in:promote_habitat_packages
- workload: artifact_published:stable:inspec:{{version_constraint}}
actions:
- bash:.expeditor/update_dockerfile.sh
- built_in:rollover_changelog
- built_in:publish_rubygems
- built_in:create_github_release
- built_in:promote_docker_images
- built_in:promote_habitat_packages
- bash:.expeditor/publish-release-notes.sh:
post_commit: true
- purge_packages_chef_io_fastly:{{target_channel}}/inspec/latest:
post_commit: true
- bash:.expeditor/announce-release.sh:
post_commit: true
- built_in:notify_chefio_slack_channels
- workload: pull_request_opened:{{github_repo}}:{{release_branch}}:*
actions:
- post_github_comment:.expeditor/templates/pull_request.mustache:
ignore_team_members:
- inspec/owners
- inspec/inspec-core-team
- built_in:github_auto_assign_author:
only_if_team_member:
- inspec/owners
- inspec/inspec-core-team

View file

@ -1,19 +0,0 @@
---
expeditor:
defaults:
buildkite:
timeout_in_minutes: 30
steps:
- label: coverage
commands:
- .expeditor/buildkite/coverage.sh
expeditor:
executor:
docker:
secrets:
COVERAGE_ID:
path: secret/coveralls/inspec/inspec
field: reporter_id

View file

@ -1 +1,182 @@
#
---
expeditor:
defaults:
buildkite:
timeout_in_minutes: 60
retry:
automatic:
limit: 1
steps:
- label: "Kitchen: resources-amazonlinux-2"
commands:
- .expeditor/buildkite/bk_linux_exec.sh
- . /var/lib/buildkite-agent/.asdf/asdf.sh
- bundle exec kitchen test resources-amazonlinux-2
artifact_paths:
- $PWD/.kitchen/logs/kitchen.log
env:
KITCHEN_YAML: kitchen.dokken.yml
DOCKER: 1
expeditor:
executor:
linux:
privileged: true
single-use: true
- label: "Kitchen: resources-centos-7"
commands:
- .expeditor/buildkite/bk_linux_exec.sh
- . /var/lib/buildkite-agent/.asdf/asdf.sh
- bundle exec kitchen test resources-centos-7
artifact_paths:
- $PWD/.kitchen/logs/kitchen.log
env:
KITCHEN_YAML: kitchen.dokken.yml
DOCKER: 1
expeditor:
executor:
linux:
privileged: true
single-use: true
- label: "Kitchen: resources-centos-8"
commands:
- .expeditor/buildkite/bk_linux_exec.sh
- . /var/lib/buildkite-agent/.asdf/asdf.sh
- bundle exec kitchen test resources-centos-8
artifact_paths:
- $PWD/.kitchen/logs/kitchen.log
env:
KITCHEN_YAML: kitchen.dokken.yml
DOCKER: 1
expeditor:
executor:
linux:
privileged: true
single-use: true
- label: "Kitchen: resources-debian-9"
commands:
- .expeditor/buildkite/bk_linux_exec.sh
- . /var/lib/buildkite-agent/.asdf/asdf.sh
- bundle exec kitchen test resources-debian-9
artifact_paths:
- $PWD/.kitchen/logs/kitchen.log
env:
KITCHEN_YAML: kitchen.dokken.yml
DOCKER: 1
expeditor:
executor:
linux:
privileged: true
single-use: true
- label: "Kitchen: resources-debian-10"
commands:
- .expeditor/buildkite/bk_linux_exec.sh
- . /var/lib/buildkite-agent/.asdf/asdf.sh
- bundle exec kitchen test resources-debian-10
artifact_paths:
- $PWD/.kitchen/logs/kitchen.log
env:
KITCHEN_YAML: kitchen.dokken.yml
DOCKER: 1
expeditor:
executor:
linux:
privileged: true
single-use: true
- label: "Kitchen: resources-fedora-latest"
commands:
- .expeditor/buildkite/bk_linux_exec.sh
- . /var/lib/buildkite-agent/.asdf/asdf.sh
- bundle exec kitchen test resources-fedora-latest
artifact_paths:
- $PWD/.kitchen/logs/kitchen.log
env:
KITCHEN_YAML: kitchen.dokken.yml
DOCKER: 1
expeditor:
executor:
linux:
privileged: true
single-use: true
- label: "Kitchen: resources-oraclelinux-7"
commands:
- .expeditor/buildkite/bk_linux_exec.sh
- . /var/lib/buildkite-agent/.asdf/asdf.sh
- bundle exec kitchen test resources-oraclelinux-7
artifact_paths:
- $PWD/.kitchen/logs/kitchen.log
env:
KITCHEN_YAML: kitchen.dokken.yml
DOCKER: 1
expeditor:
executor:
linux:
privileged: true
single-use: true
- label: "Kitchen: resources-oraclelinux-8"
commands:
- .expeditor/buildkite/bk_linux_exec.sh
- . /var/lib/buildkite-agent/.asdf/asdf.sh
- bundle exec kitchen test resources-oraclelinux-8
artifact_paths:
- $PWD/.kitchen/logs/kitchen.log
env:
KITCHEN_YAML: kitchen.dokken.yml
DOCKER: 1
expeditor:
executor:
linux:
privileged: true
single-use: true
- label: "Kitchen: resources-opensuse-leap"
commands:
- .expeditor/buildkite/bk_linux_exec.sh
- . /var/lib/buildkite-agent/.asdf/asdf.sh
- bundle exec kitchen test resources-opensuse-leap
artifact_paths:
- $PWD/.kitchen/logs/kitchen.log
env:
KITCHEN_YAML: kitchen.dokken.yml
DOCKER: 1
expeditor:
executor:
linux:
privileged: true
single-use: true
- label: "Kitchen: resources-ubuntu-1804"
commands:
- .expeditor/buildkite/bk_linux_exec.sh
- . /var/lib/buildkite-agent/.asdf/asdf.sh
- bundle exec kitchen test resources-ubuntu-1804
artifact_paths:
- $PWD/.kitchen/logs/kitchen.log
env:
KITCHEN_YAML: kitchen.dokken.yml
DOCKER: 1
expeditor:
executor:
linux:
privileged: true
single-use: true
- label: "Kitchen: resources-ubuntu-2004"
commands:
- .expeditor/buildkite/bk_linux_exec.sh
- . /var/lib/buildkite-agent/.asdf/asdf.sh
- bundle exec kitchen test resources-ubuntu-2004
artifact_paths:
- $PWD/.kitchen/logs/kitchen.log
env:
KITCHEN_YAML: kitchen.dokken.yml
DOCKER: 1
expeditor:
executor:
linux:
privileged: true
single-use: true

View file

@ -6,6 +6,7 @@ test-path-windows: omnibus/omnibus-test.ps1
fips-platforms:
- el-*-x86_64
- windows-*
- ubuntu-*-x86_64
builder-to-testers-map:
debian-9-x86_64:
- debian-9-x86_64
@ -16,16 +17,20 @@ builder-to-testers-map:
- el-6-x86_64
el-7-aarch64:
- el-7-aarch64
- el-8-aarch64
- amazon-2-aarch64
el-7-x86_64:
- el-7-x86_64
- el-8-x86_64
- amazon-2-x86_64
el-8-aarch64:
- el-8-aarch64
el-8-x86_64:
- el-8-x86_64
mac_os_x-10.14-x86_64:
- mac_os_x-10.14-x86_64
- mac_os_x-10.15-x86_64
- mac_os_x-11-x86_64
mac_os_x-11-arm64:
- mac_os_x-11-arm64
sles-12-x86_64:
- sles-12-x86_64
- sles-15-x86_64
@ -34,8 +39,7 @@ builder-to-testers-map:
ubuntu-18.04-aarch64:
- ubuntu-18.04-aarch64
- ubuntu-20.04-aarch64
ubuntu-16.04-x86_64:
- ubuntu-16.04-x86_64
ubuntu-18.04-x86_64:
- ubuntu-18.04-x86_64
- ubuntu-20.04-x86_64
windows-2012r2-x86_64:

4
.github/CODEOWNERS vendored
View file

@ -1,5 +1,5 @@
# Order is important. The last matching pattern has the most precedence.
* @inspec/inspec-core-team
docs-chef-io/** @inspec/inspec-core-team @chef/docs-team @mjingle @IanMadd
*.md @inspec/inspec-core-team @chef/docs-team @mjingle @IanMadd
docs-chef-io/** @inspec/inspec-core-team @inspec/docs-team
*.md @inspec/inspec-core-team @inspec/docs-team

12
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: bundler
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
ignore:
- dependency-name: chefstyle
versions:
- 1.6.1
- 1.6.2

View file

@ -1,24 +1,232 @@
# Change Log
<!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ -->
<!-- latest_release unreleased -->
## Unreleased
#### Bug Fixes
- Add git to Docker build [#5420](https://github.com/inspec/inspec/pull/5420) ([clintoncwolfe](https://github.com/clintoncwolfe))
<!-- latest_release -->
<!-- release_rollup since=4.26.13 -->
### Changes since 4.26.13 release
<!-- latest_release 4.41.17 -->
## [v4.41.17](https://github.com/inspec/inspec/tree/v4.41.17) (2021-08-30)
#### Merged Pull Requests
- Remove .0 from macos builder name [#5413](https://github.com/inspec/inspec/pull/5413) ([clintoncwolfe](https://github.com/clintoncwolfe)) <!-- 4.26.15 -->
- Proposed implementation for installation warnings [#5625](https://github.com/inspec/inspec/pull/5625) ([tecracer-theinen](https://github.com/tecracer-theinen))
<!-- latest_release -->
#### Bug Fixes
- Add git to Docker build [#5420](https://github.com/inspec/inspec/pull/5420) ([clintoncwolfe](https://github.com/clintoncwolfe)) <!-- 4.26.15 -->
- Don&#39;t pass -u on AIX in crontab command [#5418](https://github.com/inspec/inspec/pull/5418) ([clintoncwolfe](https://github.com/clintoncwolfe)) <!-- 4.26.14 -->
<!-- release_rollup since=4.41.2 -->
### Changes since 4.41.2 release
#### Merged Pull Requests
- Proposed implementation for installation warnings [#5625](https://github.com/inspec/inspec/pull/5625) ([tecracer-theinen](https://github.com/tecracer-theinen)) <!-- 4.41.17 -->
- Fix for security_policy resource does not return array for local groups [#5629](https://github.com/inspec/inspec/pull/5629) ([Vasu1105](https://github.com/Vasu1105)) <!-- 4.41.16 -->
- Added info about the Minitest framework in contributing doc [#5630](https://github.com/inspec/inspec/pull/5630) ([Nik08](https://github.com/Nik08)) <!-- 4.41.15 -->
- Updated security_policy resource docs [#5633](https://github.com/inspec/inspec/pull/5633) ([Vasu1105](https://github.com/Vasu1105)) <!-- 4.41.14 -->
- Replace use of wmic from security_identifier resource as it will be deprecated soon [#5636](https://github.com/inspec/inspec/pull/5636) ([Vasu1105](https://github.com/Vasu1105)) <!-- 4.41.13 -->
- Updated inspec-aws git url to replace branch to master to main [#5637](https://github.com/inspec/inspec/pull/5637) ([Vasu1105](https://github.com/Vasu1105)) <!-- 4.41.12 -->
- Fedora runtime support documented [#5628](https://github.com/inspec/inspec/pull/5628) ([Nik08](https://github.com/Nik08)) <!-- 4.41.11 -->
- Add aliyun3 support to service resource [#5578](https://github.com/inspec/inspec/pull/5578) ([elsnepal](https://github.com/elsnepal)) <!-- 4.41.10 -->
- Fix merging of included conf and main conf params in apache conf [#5623](https://github.com/inspec/inspec/pull/5623) ([Nik08](https://github.com/Nik08)) <!-- 4.41.9 -->
- Fix postgres_session error Unable to connect to database [#5619](https://github.com/inspec/inspec/pull/5619) ([Vasu1105](https://github.com/Vasu1105)) <!-- 4.41.8 -->
- Fix `--chef-license=accept` option to only show license accepted message [#5609](https://github.com/inspec/inspec/pull/5609) ([Nik08](https://github.com/Nik08)) <!-- 4.41.7 -->
- Fix `--insecure` not working with profile [#5600](https://github.com/inspec/inspec/pull/5600) ([Nik08](https://github.com/Nik08)) <!-- 4.41.6 -->
- Fix apache_conf issue when Server Root is not present in configuration [#5601](https://github.com/inspec/inspec/pull/5601) ([Nik08](https://github.com/Nik08)) <!-- 4.41.5 -->
- Fix range based filtering in filter tables [#5598](https://github.com/inspec/inspec/pull/5598) ([Nik08](https://github.com/Nik08)) <!-- 4.41.4 -->
- Build fix for ruby version 2.5 - HTML Proofer gem installation error [#5610](https://github.com/inspec/inspec/pull/5610) ([Nik08](https://github.com/Nik08)) <!-- 4.41.3 -->
<!-- release_rollup -->
<!-- latest_stable_release -->
## [v4.41.2](https://github.com/inspec/inspec/tree/v4.41.2) (2021-08-16)
#### New Features
- Add support for OPA: add resource opa_cli and opa_api [#5592](https://github.com/inspec/inspec/pull/5592) ([Vasu1105](https://github.com/Vasu1105))
#### Bug Fixes
- Pin mongo gem to 2.13.2 to avoid broken symlink [#5615](https://github.com/inspec/inspec/pull/5615) ([clintoncwolfe](https://github.com/clintoncwolfe))
#### Merged Pull Requests
- Add mongodb_session resource and docs. [#5572](https://github.com/inspec/inspec/pull/5572) ([Vasu1105](https://github.com/Vasu1105))
- Filter active controls in profile by tags [#5596](https://github.com/inspec/inspec/pull/5596) ([Nik08](https://github.com/Nik08))
- Remove empty .gitmodules file [#5616](https://github.com/inspec/inspec/pull/5616) ([tduffield](https://github.com/tduffield))
- Fix the typo in documentation file for opa_api resource [#5608](https://github.com/inspec/inspec/pull/5608) ([Vasu1105](https://github.com/Vasu1105))
<!-- latest_stable_release -->
## [v4.38.9](https://github.com/inspec/inspec/tree/v4.38.9) (2021-07-22)
#### Enhancements
- Remove default port for mssql_session, allowing named connections [#5584](https://github.com/inspec/inspec/pull/5584) ([Nik08](https://github.com/Nik08))
- Update postgresql resources to normalize it for platform supports [#5576](https://github.com/inspec/inspec/pull/5576) ([Vasu1105](https://github.com/Vasu1105))
#### Merged Pull Requests
- Oracle Session Exception Handling [#5567](https://github.com/inspec/inspec/pull/5567) ([Nik08](https://github.com/Nik08))
- Waiver file expiration dates misinterpretation fix [#5586](https://github.com/inspec/inspec/pull/5586) ([Nik08](https://github.com/Nik08))
- Need to back out x25519 gem as its causing issues for ssh [#5590](https://github.com/inspec/inspec/pull/5590) ([Vasu1105](https://github.com/Vasu1105))
- Use ruby 2.7.4 [#5602](https://github.com/inspec/inspec/pull/5602) ([clintoncwolfe](https://github.com/clintoncwolfe))
- Remove mention of AWS tests from README [#5603](https://github.com/inspec/inspec/pull/5603) ([clintoncwolfe](https://github.com/clintoncwolfe))
## [v4.38.3](https://github.com/inspec/inspec/tree/v4.38.3) (2021-07-02)
#### Merged Pull Requests
- Add support for mongodb_conf resource in InSpec [#5562](https://github.com/inspec/inspec/pull/5562) ([Vasu1105](https://github.com/Vasu1105))
- Fix AWS secret key environment variable name in docs [#5566](https://github.com/inspec/inspec/pull/5566) ([sandratiffin](https://github.com/sandratiffin))
- Fix relative links [#5556](https://github.com/inspec/inspec/pull/5556) ([IanMadd](https://github.com/IanMadd))
- Misc updates to the README [#5526](https://github.com/inspec/inspec/pull/5526) ([clintoncwolfe](https://github.com/clintoncwolfe))
## [v4.37.30](https://github.com/inspec/inspec/tree/v4.37.30) (2021-06-16)
#### Bug Fixes
- Include x25519 KEX module in omnibus build [#5563](https://github.com/inspec/inspec/pull/5563) ([clintoncwolfe](https://github.com/clintoncwolfe))
#### Merged Pull Requests
- Minor MD reformatting for dev-docs page [#5550](https://github.com/inspec/inspec/pull/5550) ([IanMadd](https://github.com/IanMadd))
- Fix mysql_session resource to raise exception if there is a error in connection or in query [#5551](https://github.com/inspec/inspec/pull/5551) ([Vasu1105](https://github.com/Vasu1105))
- Fix postgres_session resource to raise exception if there is a error in connection or in query [#5553](https://github.com/inspec/inspec/pull/5553) ([Vasu1105](https://github.com/Vasu1105))
- Restrict x25519 gem to x86 architectures [#5564](https://github.com/inspec/inspec/pull/5564) ([clintoncwolfe](https://github.com/clintoncwolfe))
## [v4.37.25](https://github.com/inspec/inspec/tree/v4.37.25) (2021-06-10)
#### Merged Pull Requests
- sshd_config is for daemon, not client - typo [#5549](https://github.com/inspec/inspec/pull/5549) ([jblaine](https://github.com/jblaine))
- Fix related to loading dependent profiles from a profile in shell [#5547](https://github.com/inspec/inspec/pull/5547) ([Nik08](https://github.com/Nik08))
## [v4.37.23](https://github.com/inspec/inspec/tree/v4.37.23) (2021-06-03)
#### Merged Pull Requests
- Update inspec init plugin [#5536](https://github.com/inspec/inspec/pull/5536) ([Vasu1105](https://github.com/Vasu1105))
- Removed support for compliance and a1 server from InSpec compliance [#5534](https://github.com/inspec/inspec/pull/5534) ([Nik08](https://github.com/Nik08))
- Add Ubuntu to list of FIPS platforms [#5533](https://github.com/inspec/inspec/pull/5533) ([clintoncwolfe](https://github.com/clintoncwolfe))
## [v4.37.20](https://github.com/inspec/inspec/tree/v4.37.20) (2021-05-26)
#### Merged Pull Requests
- Added new automate doc link for login tokens in `inspec automate login --help` command [#5529](https://github.com/inspec/inspec/pull/5529) ([Nik08](https://github.com/Nik08))
- Bugfix for `inspec detect --no-color` to not return colourful output [#5530](https://github.com/inspec/inspec/pull/5530) ([Nik08](https://github.com/Nik08))
- Drop EOL Ubuntu 16.04, build on 18.04 [#5532](https://github.com/inspec/inspec/pull/5532) ([clintoncwolfe](https://github.com/clintoncwolfe))
## [v4.37.17](https://github.com/inspec/inspec/tree/v4.37.17) (2021-05-20)
#### Enhancements
- Fix for port resource performance: adding more specific search while using ss command [#5522](https://github.com/inspec/inspec/pull/5522) ([Vasu1105](https://github.com/Vasu1105))
#### Merged Pull Requests
- Fix the lint and failing test for windows_feature resource [#5524](https://github.com/inspec/inspec/pull/5524) ([Vasu1105](https://github.com/Vasu1105))
- Support zfs_pool and zfs_dataset resources on Linux. Handled #5075 [#5523](https://github.com/inspec/inspec/pull/5523) ([kannanr](https://github.com/kannanr))
- Add basic docs for toml resource [#5514](https://github.com/inspec/inspec/pull/5514) ([clintoncwolfe](https://github.com/clintoncwolfe))
- Add CI-CD docs [#5489](https://github.com/inspec/inspec/pull/5489) ([clintoncwolfe](https://github.com/clintoncwolfe))
- Add explicit RHEL8 builders to omnibus build [#5527](https://github.com/inspec/inspec/pull/5527) ([clintoncwolfe](https://github.com/clintoncwolfe))
- Changes returns nil on file non-existence through matcher `more_permissive_than` [#5519](https://github.com/inspec/inspec/pull/5519) ([Nik08](https://github.com/Nik08))
- Update control-eval Readme docs. [#5516](https://github.com/inspec/inspec/pull/5516) ([Vasu1105](https://github.com/Vasu1105))
- Added Common Errors page doc [#5517](https://github.com/inspec/inspec/pull/5517) ([Nik08](https://github.com/Nik08))
## [v4.37.8](https://github.com/inspec/inspec/tree/v4.37.8) (2021-05-12)
#### Merged Pull Requests
- Update `bond0` example to use params properly [#5518](https://github.com/inspec/inspec/pull/5518) ([gscho](https://github.com/gscho))
- HTTP resource response body coerced into UTF-8 [#5510](https://github.com/inspec/inspec/pull/5510) ([Nik08](https://github.com/Nik08))
- Fixed `automate login` fake feedback on failure [#5509](https://github.com/inspec/inspec/pull/5509) ([Nik08](https://github.com/Nik08))
- Document auxiliary reporter options on the reporter docs page [#5504](https://github.com/inspec/inspec/pull/5504) ([clintoncwolfe](https://github.com/clintoncwolfe))
- Update chefstyle requirement from ~&gt; 1.7.1 to ~&gt; 2.0.3 [#5508](https://github.com/inspec/inspec/pull/5508) ([dependabot[bot]](https://github.com/dependabot[bot]))
- Update Hugo and correct how build previews are generated [#5507](https://github.com/inspec/inspec/pull/5507) ([IanMadd](https://github.com/IanMadd))
- Modified windows_feature to indicate enabled rather than just available [#5506](https://github.com/inspec/inspec/pull/5506) ([jwdean](https://github.com/jwdean))
- Remove outdated instructions about testing AWS and Azure resources [#5499](https://github.com/inspec/inspec/pull/5499) ([clintoncwolfe](https://github.com/clintoncwolfe))
## [v4.37.0](https://github.com/inspec/inspec/tree/v4.37.0) (2021-05-05)
#### Enhancements
- Reinstate resource testing on supported platforms using Test-Kitchen [#5204](https://github.com/inspec/inspec/pull/5204) ([clintoncwolfe](https://github.com/clintoncwolfe))
#### Bug Fixes
- Fix : windows_firewall_rule fails to validate more than 1 rule depending on how it&#39;s executed [#5502](https://github.com/inspec/inspec/pull/5502) ([Vasu1105](https://github.com/Vasu1105))
#### Merged Pull Requests
- Update openssl to 1.1.1k on macos [#5493](https://github.com/inspec/inspec/pull/5493) ([tas50](https://github.com/tas50))
- Update Ruby in omnibus packages to 2.7.3 [#5492](https://github.com/inspec/inspec/pull/5492) ([tas50](https://github.com/tas50))
- Make sure we use chef-telemetry 1.0.8+ [#5491](https://github.com/inspec/inspec/pull/5491) ([tas50](https://github.com/tas50))
- Upgrade to GitHub-native Dependabot [#5488](https://github.com/inspec/inspec/pull/5488) ([dependabot-preview[bot]](https://github.com/dependabot-preview[bot]))
- Fixes for the integration-resources pipeline [#5501](https://github.com/inspec/inspec/pull/5501) ([clintoncwolfe](https://github.com/clintoncwolfe))
- Fix bad link [#5498](https://github.com/inspec/inspec/pull/5498) ([IanMadd](https://github.com/IanMadd))
- Fix undefined method `+&#39; for nil:NilClass\n\nProfile: - when using profile dependencies and require_controls [#5487](https://github.com/inspec/inspec/pull/5487) ([Vasu1105](https://github.com/Vasu1105))
- Remove coverage testing [#5500](https://github.com/inspec/inspec/pull/5500) ([clintoncwolfe](https://github.com/clintoncwolfe))
- Added alias command `automate` for `inspec compliance` [#5490](https://github.com/inspec/inspec/pull/5490) ([Nik08](https://github.com/Nik08))
## [v4.36.4](https://github.com/inspec/inspec/tree/v4.36.4) (2021-04-29)
#### New Features
- Add selinux resource with basic feature support [#5458](https://github.com/inspec/inspec/pull/5458) ([Vasu1105](https://github.com/Vasu1105))
- New input option `pattern` added for DSL and metadata inputs [#5466](https://github.com/inspec/inspec/pull/5466) ([Nik08](https://github.com/Nik08))
#### Enhancements
- Add selinux resource support for modules and booleans [#5463](https://github.com/inspec/inspec/pull/5463) ([Vasu1105](https://github.com/Vasu1105))
#### Bug Fixes
- Fix for group resource when member does not exist [#5470](https://github.com/inspec/inspec/pull/5470) ([Nik08](https://github.com/Nik08))
#### Merged Pull Requests
- Update faraday requirement from &gt;= 0.9.0, &lt; 1.4 to &gt;= 0.9.0, &lt; 1.5 [#5469](https://github.com/inspec/inspec/pull/5469) ([dependabot-preview[bot]](https://github.com/dependabot-preview[bot]))
- Minor fix - Method expected to return boolean but it was returning nil if condition check fails [#5480](https://github.com/inspec/inspec/pull/5480) ([Vasu1105](https://github.com/Vasu1105))
- updating Gemfile to support environment variables [#5485](https://github.com/inspec/inspec/pull/5485) ([jayashrig158](https://github.com/jayashrig158))
- Group &amp; Groups doc updated - about using local and etc groups [#5483](https://github.com/inspec/inspec/pull/5483) ([Nik08](https://github.com/Nik08))
- Added new property `members_array` for group &amp; groups resources. [#5479](https://github.com/inspec/inspec/pull/5479) ([Nik08](https://github.com/Nik08))
## [v4.33.1](https://github.com/inspec/inspec/tree/v4.33.1) (2021-04-21)
#### New Features
- Optionally include controls source code in CLI reporter [#5465](https://github.com/inspec/inspec/pull/5465) ([clintoncwolfe](https://github.com/clintoncwolfe))
#### Merged Pull Requests
- Update postgres_ident_conf.md [#5461](https://github.com/inspec/inspec/pull/5461) ([tobiasbp](https://github.com/tobiasbp))
- Remove default of 3600 seconds for command timeout [#5472](https://github.com/inspec/inspec/pull/5472) ([clintoncwolfe](https://github.com/clintoncwolfe))
## [v4.32.0](https://github.com/inspec/inspec/tree/v4.32.0) (2021-04-14)
#### New Features
- Added ability to pass inputs to InSpec shell using input file and cli [#5452](https://github.com/inspec/inspec/pull/5452) ([Nik08](https://github.com/Nik08))
## [v4.31.1](https://github.com/inspec/inspec/tree/v4.31.1) (2021-04-08)
#### Bug Fixes
- Use default command timeout value if timeout is 0 [#5455](https://github.com/inspec/inspec/pull/5455) ([clintoncwolfe](https://github.com/clintoncwolfe))
## [v4.31.0](https://github.com/inspec/inspec/tree/v4.31.0) (2021-04-07)
#### New Features
- Add --docker-url CLI option [#5445](https://github.com/inspec/inspec/pull/5445) ([clintoncwolfe](https://github.com/clintoncwolfe))
#### Merged Pull Requests
- Fix for Deprecation warning and FilterTable::ExceptionCatcher to show exact failure message. [#5441](https://github.com/inspec/inspec/pull/5441) ([Vasu1105](https://github.com/Vasu1105))
- Update inputs.md [#5449](https://github.com/inspec/inspec/pull/5449) ([IanMadd](https://github.com/IanMadd))
- Add timeout option to command resource [#5443](https://github.com/inspec/inspec/pull/5443) ([clintoncwolfe](https://github.com/clintoncwolfe))
- Update platforms doc [#5442](https://github.com/inspec/inspec/pull/5442) ([IanMadd](https://github.com/IanMadd))
- Bug fix for loading hashmap inputs consistently [#5446](https://github.com/inspec/inspec/pull/5446) ([Nik08](https://github.com/Nik08))
## [v4.29.3](https://github.com/inspec/inspec/tree/v4.29.3) (2021-03-25)
#### Bug Fixes
- Fix for -controls option is not working as expected. [#5434](https://github.com/inspec/inspec/pull/5434) ([Vasu1105](https://github.com/Vasu1105))
- Fix for executing git profiles independent of the name of the default branch [#5438](https://github.com/inspec/inspec/pull/5438) ([Nik08](https://github.com/Nik08))
#### Merged Pull Requests
- Minor Docs edits [#5433](https://github.com/inspec/inspec/pull/5433) ([IanMadd](https://github.com/IanMadd))
- Add quotation around -name option for apt resource to work properly with zsh [#5437](https://github.com/inspec/inspec/pull/5437) ([ymotongpoo](https://github.com/ymotongpoo))
- Updates profile init for cloud platforms to use inputs [#5435](https://github.com/inspec/inspec/pull/5435) ([collinmcneese](https://github.com/collinmcneese))
- Move Passthrough Config from Automate to JSON Reporter [#5430](https://github.com/inspec/inspec/pull/5430) ([tohch4](https://github.com/tohch4))
- Update codeowners for docs [#5440](https://github.com/inspec/inspec/pull/5440) ([IanMadd](https://github.com/IanMadd))
- Improve resource page menu titles [#5439](https://github.com/inspec/inspec/pull/5439) ([IanMadd](https://github.com/IanMadd))
- Add m1 support to MacOS build list [#5432](https://github.com/inspec/inspec/pull/5432) ([clintoncwolfe](https://github.com/clintoncwolfe))
## [v4.28.0](https://github.com/inspec/inspec/tree/v4.28.0) (2021-03-17)
#### New Features
- Support &#39;clear_cache&#39; [#5266](https://github.com/inspec/inspec/pull/5266) ([Schwad](https://github.com/Schwad))
#### Enhancements
- Fixes #5373 : Add option to filter empty profiles from report [#5425](https://github.com/inspec/inspec/pull/5425) ([Vasu1105](https://github.com/Vasu1105))
#### Bug Fixes
- Don&#39;t pass -u on AIX in crontab command [#5418](https://github.com/inspec/inspec/pull/5418) ([clintoncwolfe](https://github.com/clintoncwolfe))
- Add git to Docker build [#5420](https://github.com/inspec/inspec/pull/5420) ([clintoncwolfe](https://github.com/clintoncwolfe))
#### Merged Pull Requests
- Remove .0 from macos builder name [#5413](https://github.com/inspec/inspec/pull/5413) ([clintoncwolfe](https://github.com/clintoncwolfe))
- Fix backtrace occurs when using `cmp` to compare nil to an expectation [#5427](https://github.com/inspec/inspec/pull/5427) ([Vasu1105](https://github.com/Vasu1105))
- Clarify include matcher docs on crontab resource [#5419](https://github.com/inspec/inspec/pull/5419) ([clintoncwolfe](https://github.com/clintoncwolfe))
- Update README to add note about Ruby 2.5 support [#5424](https://github.com/inspec/inspec/pull/5424) ([clintoncwolfe](https://github.com/clintoncwolfe))
- Expose conf_path, content, and params on auditd_conf [#5422](https://github.com/inspec/inspec/pull/5422) ([yarick](https://github.com/yarick))
- Update json_schemer requirement from &gt;= 0.2.1, &lt; 0.2.18 to &gt;= 0.2.1, &lt; 0.2.19 [#5423](https://github.com/inspec/inspec/pull/5423) ([dependabot-preview[bot]](https://github.com/dependabot-preview[bot]))
## [v4.26.13](https://github.com/inspec/inspec/tree/v4.26.13) (2021-02-24)
#### Bug Fixes
@ -33,7 +241,6 @@
- Update chefstyle requirement from ~&gt; 1.5.7 to ~&gt; 1.7.1 [#5409](https://github.com/inspec/inspec/pull/5409) ([dependabot-preview[bot]](https://github.com/dependabot-preview[bot]))
- Document the json-automate reporter [#5408](https://github.com/inspec/inspec/pull/5408) ([clintoncwolfe](https://github.com/clintoncwolfe))
- Switch to MacOS 10.14 builder [#5415](https://github.com/inspec/inspec/pull/5415) ([clintoncwolfe](https://github.com/clintoncwolfe))
<!-- latest_stable_release -->
## [v4.26.4](https://github.com/inspec/inspec/tree/v4.26.4) (2021-01-27)

View file

@ -26,7 +26,7 @@ We have a 3 step process for contributions:
Chef Projects are built to last. We strive to ensure high quality throughout the experience. In order to ensure this, we require that all pull requests to Chef projects meet these specifications:
1. **Tests:** To ensure high quality code and protect against future regressions, we require all the code in Chef Projects to have at least unit test coverage. See the [test/unit](https://github.com/inspec/inspec/tree/master/test/unit)
directory for the existing tests and use ```bundle exec rake test``` to run them.
directory for the existing tests and use ```bundle exec rake test``` to run them. It should be good to know InSpec uses [minitest](https://github.com/seattlerb/minitest) as a testing framework.
2. **Green CI Tests:** We use [Travis CI](https://travis-ci.org/) and/or [AppVeyor](https://www.appveyor.com/) CI systems to test all pull requests. We require these test runs to succeed on every pull request before being merged.
3. **Up-to-date Documentation:** Every code change should be reflected in an update for our [documentation](https://github.com/inspec/inspec/tree/master/docs-chef-io). We expect PRs to update the documentation with the code change.

View file

@ -1,7 +1,7 @@
FROM ubuntu:18.04
LABEL maintainer="Chef Software, Inc. <docker@chef.io>"
ARG VERSION=4.26.13
ARG VERSION=4.41.2
ARG CHANNEL=stable
ENV PATH=/opt/inspec/bin:/opt/inspec/embedded/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

24
Gemfile
View file

@ -28,10 +28,14 @@ group :omnibus do
end
group :test do
gem "chefstyle", "~> 1.7.1"
gem "chefstyle", "~> 2.0.3"
gem "concurrent-ruby", "~> 1.0"
gem "html-proofer", platforms: :ruby # do not attempt to run proofer on windows
gem "json_schemer", ">= 0.2.1", "< 0.2.18"
if Gem.ruby_version.to_s.start_with?("2.5")
gem "html-proofer", "= 3.19.1" , platforms: :ruby # do not attempt to run proofer on windows
else
gem "html-proofer", platforms: :ruby # do not attempt to run proofer on windows
end
gem "json_schemer", ">= 0.2.1", "< 0.2.19"
gem "m"
gem "minitest-sprint", "~> 1.0"
gem "minitest", "~> 5.5"
@ -48,3 +52,17 @@ end
group :deploy do
gem "inquirer"
end
# Only include Test Kitchen support if we are on Ruby 2.7 or higher
# as chef-zero support requires Ruby 2.6
# See https://github.com/inspec/inspec/pull/5341
if Gem.ruby_version >= Gem::Version.new("2.7.0")
group :kitchen do
gem "berkshelf"
gem "chef", ">= 16.0" # Required to allow net-ssh > 6
gem "test-kitchen", ">= 2.8"
gem "kitchen-inspec", ">= 2.0"
gem "kitchen-dokken", ">= 2.11"
gem "git"
end
end

View file

@ -55,7 +55,12 @@ inspec exec test.rb -t docker://container_id
## Installation
Chef InSpec requires Ruby ( >= 2.5 ).
Chef InSpec requires Ruby ( >= 2.6 ). Ruby 2.5 support is limited and requires Bundler with an entry in the Gemfile:
```
# 16.7.23 required ruby 2.6+
gem "chef-utils", "< 16.7.23"
```
Note: Versions of Chef InSpec 4.0 and later require accepting the EULA to use. Please visit the [license acceptance page](https://docs.chef.io/chef_license_accept.html) on the Chef docs site for more information.
@ -73,7 +78,9 @@ curl https://omnitruck.chef.io/install.sh | sudo bash -s -- -P inspec
### Install it via rubygems.org
When installing from source, gem dependencies may require ruby build tools to be installed.
Installing Chef InSpec from source may require installing ruby build tools to manage gem dependencies. (A compiler-free variant is available with reduced functionality; use `inspec-core-bin` and `inspec-core`.)
To install build tools, use your package manager.
For CentOS/RedHat/Fedora:
@ -172,17 +179,18 @@ You should now be able to run:
```bash
$ inspec --help
Commands:
inspec archive PATH # archive a profile to tar.gz (default) ...
inspec check PATH # verify all tests at the specified PATH
inspec compliance SUBCOMMAND ... # Chef Compliance commands
inspec detect # detect the target OS
inspec exec PATH(S) # run all test files at the specified PATH.
inspec help [COMMAND] # Describe available commands or one spe...
inspec init TEMPLATE ... # Scaffolds a new project
inspec json PATH # read all tests in PATH and generate a ...
inspec shell # open an interactive debugging shell
inspec supermarket SUBCOMMAND ... # Supermarket commands
inspec version # prints the version of this tool
inspec archive PATH # archive a profile to tar.gz (default) ...
inspec check PATH # verify all tests at the specified PATH
inspec automate SUBCOMMAND ... # Chef Automate commands
inspec compliance SUBCOMMAND ... # Chef Automate commands (backwards compatible alias)
inspec detect # detect the target OS
inspec exec PATH(S) # run all test files at the specified PATH.
inspec help [COMMAND] # Describe available commands or one spe...
inspec init TEMPLATE ... # Scaffolds a new project
inspec json PATH # read all tests in PATH and generate a ...
inspec shell # open an interactive debugging shell
inspec supermarket SUBCOMMAND ... # Supermarket commands
inspec version # prints the version of this tool
Options:
[--diagnose], [--no-diagnose] # Show diagnostics (versions, configurations)
@ -203,14 +211,6 @@ describe port(443) do
end
```
* Use approved strong ciphers - This test ensures that only enterprise-compliant ciphers are used for SSH servers.
```ruby
describe sshd_config do
   its('Ciphers') { should eq('chacha20-poly1305@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr') }
end
```
* Test your `kitchen.yml` file to verify that only Vagrant is configured as the driver. The %w() formatting will
pass rubocop linting and allow you to access nested mappings.
@ -332,6 +332,7 @@ In addition, runtime support is provided for:
| macOS | 10.14+ | x86_64 |
| Debian | 9, 10 | x86_64 |
| RHEL | 6, 7, 8 | x86_64 |
| Fedora | 29+ | x86_64 |
| Ubuntu | 16.04+ | x86_64 |
| Windows | 8+ | x86_64 |
| Windows | 2012+ | x86_64 |
@ -360,6 +361,8 @@ You may also [browse the Supermarket for shared Compliance Profiles](https://sup
## Kudos
Chef InSpec was originally created by Christoph Hartmann ([@chris-rock](https://github.com/chris-rock)) and Dominik Richter ([@arlimus](https://github.com/arlimus)).
Chef InSpec is inspired by the wonderful [Serverspec](http://serverspec.org) project. Kudos to [mizzy](https://github.com/mizzy) and [all contributors](https://github.com/mizzy/serverspec/graphs/contributors)!
The AWS resources were inspired by [inspec-aws](https://github.com/arothian/inspec-aws) from [arothian](https://github.com/arothian).
@ -382,11 +385,10 @@ As a reminder, all participants are expected to follow the [Code of Conduct](htt
## Testing Chef InSpec
We offer `unit`, `integration`, and `aws` tests.
We offer `unit` and `integration` tests.
- `unit` tests ensure the intended behaviour of the implementation
- `integration` tests run against Docker-based VMs via test-kitchen and [kitchen-inspec](https://github.com/chef/kitchen-inspec)
- `aws` tests exercise the AWS resources against real AWS accounts
### Unit tests
@ -425,42 +427,35 @@ In addition, these test require Docker to be available on your machine or a remo
List the various test instances available:
```bash
bundle exec kitchen list
KITCHEN_YAML=kitchen.dokken.yml bundle exec kitchen list
```
The platforms and test suites are configured in the `.kitchen.yml` file. Once you know which instance you wish to test, test that instance:
The platforms and test suites are configured in the `kitchen.dokken.yml` file. Once you know which instance you wish to test, test that instance:
```bash
bundle exec kitchen test <INSTANCE_NAME>
KITCHEN_YAML=kitchen.dokken.yml bundle exec kitchen test <INSTANCE_NAME>
```
You may test all instances in parallel with:
```bash
bundle exec kitchen test -c
KITCHEN_YAML=kitchen.dokken.yml bundle exec kitchen test -c 3
```
### AWS Tests
Use the rake task `bundle exec rake test:aws` to test the AWS resources against a pair of real AWS accounts.
Please see [TESTING_AGAINST_AWS.md](./test/integration/aws/TESTING_AGAINST_AWS.md) for details on how to setup the needed AWS accounts to perform testing.
### Azure Tests
Use the rake task `bundle exec rake test:azure` to test the Azure resources against an Azure account.
Please see [TESTING_AGAINST_AZURE.md](./test/integration/azure/TESTING_AGAINST_AZURE.md) for details on how to setup the needed Azure accounts to perform testing.
## License
| | |
| -------------- | ----------------------------------------- |
| **Author:** | Dominik Richter (<drichter@chef.io>) |
| **Author:** | Christoph Hartmann (<chartmann@chef.io>) |
| **Copyright:** | Copyright (c) 2015 Vulcano Security GmbH. |
| **Copyright:** | Copyright (c) 2017-2018 Chef Software Inc.|
| **License:** | Apache License, Version 2.0 |
| | |
| -------------- | ---------------------------------------------- |
| **Author:** | Dominik Richter (<drichter@chef.io>) |
| **Author:** | Christoph Hartmann (<chartmann@chef.io>) |
| **Copyright:** | Copyright (c) 2015 Vulcano Security GmbH. |
| **Copyright:** | Copyright (c) 2017-2020 Chef Software Inc. |
| **Copyright:** | Copyright (c) 2020-2021 Progress Software Corp.|
| **License:** | Apache License, Version 2.0 |
| **License:** | Chef End User License Agreement |
Chef InSpec is distributed under the Apache License, Version 2.0.
Permission to use the software is governed by the [Chef EULA](https://docs.chef.io/chef_license_accept.html).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View file

@ -255,14 +255,14 @@ namespace :test do
# Inject a prerequisite task
task unit: [:accept_license]
task :integration, [:os] do |task, args|
task :kitchen, [:os] do |task, args|
concurrency = ENV["CONCURRENCY"] || 1
os = args[:os] || ENV["OS"] || ""
ENV["DOCKER"] = "true" if ENV["docker"].nil?
sh("bundle exec kitchen test -c #{concurrency} #{os}")
end
# Inject a prerequisite task
task integration: [:accept_license]
task kitchen: [:accept_license]
task :ssh, [:target] do |_t, args|
tests_path = File.join(File.dirname(__FILE__), "test", "integration", "test", "integration", "default")

View file

@ -1 +1 @@
4.26.15
4.41.17

133
dev-docs/ci-cd.md Normal file
View file

@ -0,0 +1,133 @@
# About InSpec's Continuous Integration and Continuous Delivery Setup
## Major Components
### Expeditor
[Expeditor](https://expeditor.chef.io/) is the main coordinator of all CI-CD activity at Chef. It is configured through a [YAML file](https://github.com/inspec/inspec/blob/master/.expeditor/config.yml).
### BuildKite
[Buildkite](https://buildkite.com/chef) is the engine that actually executes all of the tests and builds for InSpec. While Buildkite coordinates all of the work, the actual infrastructure is managed by Chef in a variety of locations, including various clouds and datacenters.
Buildkite is divided into two orgs, [Chef](https://buildkite.com/chef) and [Chef-OSS](https://buildkite.com/chef-oss) (Open Source Software). Chef is private and Chef-OSS is public.
You will need to have an account on BuildKite and be a member of both orgs to fully utilize the system.
### Rakefile
The [Rakefile](https://github.com/inspec/inspec/blob/master/Rakefile) defines the tests harness to be run. Most of the test scripts come down to executing "rake test" or similar.
### Omnibus
Omnibus is a system for building OS-specific packages of software, including all dependencies including Ruby runtimes. We use Omnibus to make RPMs, DEBs, MSIs, DMGs, and several other OS-specific formats that deploy inspec and its dependencies natively to the OS.
The omnibus configuration for InSpec is stored at https://github.com/inspec/inspec/tree/master/omnibus and the main configuration file is [inspec.rb](https://github.com/inspec/inspec/blob/master/omnibus/config/projects/inspec.rb).
### Rubygems
InSpec is published as a set of 4 gems - inspec, inspec-core, inspec-bin, and inspec-core-bin. When we release a new version to the public (a process we call "promotion" and typically happens on Wednesdays), we publish to rubygems.org.
Rubygems are configured by declaring them in the expeditor configuration file in the `rubygems` section.
### Artifactory
Artifactory stores build artifacts (such as RPMs, MSIs, and gems) on a temporary basis. Artifactory is protected by the Progress VPN. [Artifactory inspec package search](http://artifactory.chef.co/ui/packages?name=inspec&type=packages).
## What Happens when...
### A PR is opened
When a PR is opened, the subscription [workload: pull_request_opened:{{agent_id}}:*](https://github.com/inspec/inspec/blob/cb2abf2e10906bba4df24b2ed18ec51b0931eff2/.expeditor/config.yml#L173) is activated. In addition, several defaults also apply.
One default pipeline that gets activated is the Buildkite [master verify pipeline](https://buildkite.com/chef-oss/inspec-inspec-master-verify). This default is documented [here](https://expeditor.chef.io/docs/pipelines/verify/).
#### verify pipeline
The verify pipeline runs the linter, the unit tests, and the functional tests. It verifies that the code being submitted is sound.
The verify pipeline is defined first in the [verify.pipeline.yml](https://github.com/inspec/inspec/blob/master/.expeditor/verify.pipeline.yml) file, which defines the separate Ruby versions, platforms, and environment variables to be passed to each one. Each runner calls a shell script, either [verify.sh](https://github.com/inspec/inspec/blob/master/.expeditor/buildkite/verify.sh) or [verify.ps1](https://github.com/inspec/inspec/blob/master/.expeditor/buildkite/verify.ps1). These scripts are thin wrappers that install Bundler dependencies from a cache, then call into the Rakefile.
#### habitat artifact pipeline
The habitat artifact pipeline runs a smoke test to verify that the habitat build of inspec is valid.
The habitat artifact pipeline is defined first in the [artifact.habitat.yml](https://github.com/inspec/inspec/blob/master/.expeditor/artifact.habitat.yml) file. It simply defines a linux runner and a windows runner, each with a dedicated script, [artifact.habitat.test.sh](https://github.com/inspec/inspec/blob/master/.expeditor/buildkite/artifact.habitat.test.sh) or [artifact.habitat.test.ps1](https://github.com/inspec/inspec/blob/master/.expeditor/buildkite/artifact.habitat.test.ps1). The scripts install habitat, setup an origin key, build the package, and then run a [Rakefile](https://github.com/inspec/inspec/blob/master/test/artifact/Rakefile)
### A PR is merged
When a PR is merged, the Expeditor actions under `merge_actions` are executed.
Watch the Slack channel #inspec-notify for messages about the success or failure of various steps.
Connect to the Progress VPN to fetch Expeditor logs in the event of a failure.
#### Version Bumping
This is controlled by the `built_in:bump_version` and `bash:.expeditor/update_version.sh` subscriptions.
If there are no GitHub labels on the PR, the patchlevel of the version will be bumped by executing the [.expeditor/update_version.sh](https://github.com/inspec/inspec/blob/master/.expeditor/update_version.sh) script. First the VERSION file is updated, then the script runs to update the versions in the Ruby files.
`built_in:bump_version` is in charge of bumping versions in VERSION, and is controlled by GitHub labels on the PR. Most, though not all, PRs should not have any Expeditor control labels.
Here are the Expeditor control labels, and the circumstances under which they should be used:
* Expeditor: Bump Minor Version - Use when a significant new feature is being released.
* Expeditor: Bump Major Version - Use when a major release is made - rarely used.
* Expeditor: Skip Version Bump - Use for non-code-change PRs, such as website or CI changes.
#### Build Omnibus Packages
This is controlled by the `trigger_pipeline:omnibus/release` subscription.
The Omnibus build creates operating-system-specific packages for each platform on which we release Chef InSpec. Its [expeditor configuration](https://github.com/inspec/inspec/blob/44fe144732e1e0abb2594957a880c5f1821e7774/.expeditor/config.yml#L133) drives a [Buildkite configuration](https://github.com/inspec/inspec/blob/master/.expeditor/release.omnibus.yml), which lists exactly which platforms to build.
The Omnibus build is generally reliable, if somewhat slow.
When the omnibus build succeeds, omnitruck delivers the packages to various package repos in `unstable` channels for public consumption. The packages are also delivered to [Artifactory](http://artifactory.chef.co/ui/repos/tree/General/omnibus-unstable-local%2Fcom%2Fgetchef%2Finspec) (VPN required)
#### Chef Habitat Build
The Chef Habitat build creates Habitat .hart packages for Linux and Windows. The [Expeditor configuration](https://github.com/inspec/inspec/blob/44fe144732e1e0abb2594957a880c5f1821e7774/.expeditor/config.yml#L138) drives a [Buildkite configuration](https://github.com/inspec/inspec/blob/master/.expeditor/build.habitat.yml).
When the hab build succeeds, the packages will be placed on the Hab builder in the `unstable` channel for public consumption.
#### Docker Image Built and Released
We also release a Docker image (see [expeditor config](https://github.com/inspec/inspec/blob/44fe144732e1e0abb2594957a880c5f1821e7774/.expeditor/config.yml#L150)), which contains a Linux system and Chef InSpec installed from a gem, with the ENTRYPOINT of the Docker image being `inspec` (see [Dockerfile](https://github.com/inspec/inspec/blob/master/Dockerfile)). It's a simple way to ship the dependencies of `inspec`.
When it succeeds, the Docker build is labeled as `current`.
#### Gems Built and Placed on Artifactory
The `inspec`, `inspec-bin`, `inspec-core`, and `inspec-core-bin` gems are all built and placed on the internal Chef [Artifactory](http://artifactory.chef.co/ui/packages?name=inspec&type=packages) (VPN required) server. During promotion later, they publish to rubygems.org.
The difference between the gems is as follows:
* `inspec` is a library gem, with full heavyweight dependencies, not encumbered by commercial licensing
* `inspec-bin` contains an `inspec` executable and is encumbered by commercial licensing
* `inspec-core` is a library gem, with lightweight dependencies and no compilation required at install time, and is not encumbered by commercial licensing
* `inspec-core-bin` contains an `inspec` executable and is encumbered by commercial licensing
### A release is promoted
When expeditor is told to promote a release, using the slack command `/expeditor promote inspec/inspec:master 4.36.4` (for example), Expeditor automatically promotes the Omnibus packages from the unstable channel to the stable channel, publishing them to the various downloads sites. It also creates the `artifact_published:stable` event, which has numerous [actions subscribed](https://github.com/inspec/inspec/blob/8a93f08a13d6bde8f87e447ff4246801bef80f8c/.expeditor/config.yml#L158).
Some of the more important ones:
#### Update and publish the docker image
The Dockerfile is updated - mainly to update version numbers - and then the published Docker image is tagged with the labels "stable" and "latest".
#### Rubygems are published to rubygems,org
The gems are taken from Artifactory and published to Rubygems.org. This is done using an Expeditor built-in action. The gems must be owned by the user `chef`.
#### Release notes are published
The [pending release notes](https://github.com/inspec/inspec/wiki/Pending-Release-Notes) are copied to AWS S3 by a [script](https://github.com/inspec/inspec/blob/master/.expeditor/publish-release-notes.sh), and then reset back to an empty state. Another [script](https://github.com/inspec/inspec/blob/master/.expeditor/announce-release.sh) takes the release notes from S3 and creates a post on Discourse.

View file

@ -2,11 +2,13 @@
## Purpose
The `compliance` set of subcommands handle user-initiated communication with Chef Automate. The commands are provided so that a user can interact with an Automate installation.
The `automate` set of subcommands handle user-initiated communication with Chef Automate. The commands are provided so that a user can interact with an Automate installation.
`inspec compliance` is somewhat analogous to `knife` in that it can be used to upload, download, and manage profiles for distribution to other clients.
`inspec automate` is somewhat analogous to `knife` in that it can be used to upload, download, and manage profiles for distribution to other clients.
When Automate initiates scans, the `compliance` subcommand is not used.
When Automate initiates scans, the `automate` subcommand is not used.
`inspec compliance` is a backwards compatible alias for `inspec automate` and works the same way
## Operational Notes
@ -53,7 +55,7 @@ Actual HTTP communication is handled by `InspecPlugins::Compliance::HTTP`, again
#### lib/http.rb
This is probably unneccesary. It is a wrapper around Net:HTTP. Instead, we should probably be using a REST API wrapper or something similar.
This is probably unnecessary. It is a wrapper around Net:HTTP. Instead, we should probably be using a REST API wrapper or something similar.
#### lib/support.rb
@ -65,8 +67,9 @@ There are several other minor commands not listed here - see `lib/cli.rb` for a
### login
Saves a credentials file locally. Future invocations of `inspec compliance` use the credentials file to authenticate.
Saves a credentials file locally. Future invocations of `inspec automate` or `inspec compliance` use the credentials file to authenticate.
`be inspec automate login --user=admin --token='1234567890asdfghjkl' --insecure https://chef-automate.test` or
`be inspec compliance login --user=admin --token='1234567890asdfghjkl' --insecure https://chef-automate.test`
Here are the results of running login, from `.inspec/compliance/config.json`:

View file

@ -6,33 +6,55 @@
## Tips
* In the early days of Chef InSpec / ServerSpec, controls were called "rules". Throughout various places in the code, the word "rule" is used to mean "control". Make the mental subsitution.
* In the early days of Chef InSpec / ServerSpec, controls were called "rules". Throughout various places in the code, the word "rule" is used to mean "control". Make the mental substitution.
* Chef InSpec supports reading profiles from tarballs, local files, git repos, etc. So, don't count on local file reading; instead it uses a special source reader to obtain the contents of the files.
## The basics of the stack
#5 Inspec::Profile.collect_tests(include_list#Array) at lib/inspec/profile.rb:167
#4 Hash.each at lib/inspec/profile.rb:167
#3 block in Inspec::Profile.block in collect_tests(include_list#Array) at lib/inspec/profile.rb:170
#2 Inspec::ProfileContext.load_control_file(*args#Array) at lib/inspec/profile_context.rb:141
#1 Inspec::ProfileContext.control_eval_context at lib/inspec/profile_context.rb:58
#0 #<Class:Inspec::ControlEvalContext>.create(profile_context#Inspec::ProfileContext, resources_dsl#Module) at lib/inspec/control_eval_context.rb:41
## A profile context is created
Like many things in Chef InSpec core, a profile context is an anonymous class. (verify)
Profile context gets instantiated as soon as the Profile gets created.
Additionally, a control_eval_context is created. It is an instance of an anonymous class; it has a class<->relationship with its profile context. See `lib/inspec/control_eval_context.rb`.
0 Inspec::ProfileContext.initialize(profile_id#String, backend#Inspec::Backend, conf#Hash) at inspec/lib/inspec/profile_context.rb:20
ͱ-- #1 Class.new(*args) at inspec/lib/inspec/profile_context.rb:13
#2 #<Class:Inspec::ProfileContext>.for_profile(profile#Inspec::Profile, backend#Inspec::Backend) at inspec/lib/inspec/profile_context.rb:13
#3 Inspec::Profile.initialize(source_reader#SourceReaders::InspecReader, options#Hash) at inspec/lib/inspec/profile.rb:149
ͱ-- #4 Class.new(*args) at inspec/lib/inspec/profile.rb:61
#5 #<Class:Inspec::Profile>.for_path(path#String, opts#Hash) at inspec/lib/inspec/profile.rb:61
#6 #<Class:Inspec::Profile>.for_fetcher(fetcher#Inspec::CachedFetcher, config#Hash) at inspec/lib/inspec/profile.rb:68
#7 #<Class:Inspec::Profile>.for_target(target#String, opts#Hash) at inspec/lib/inspec/profile.rb:74
#8 Inspec::Runner.add_target(target#String, _opts#Array) at inspec/lib/inspec/runner.rb:198
#9 block in Inspec::InspecCLI.block in exec(*targets#Array) at inspec/lib/inspec/cli.rb:283
ͱ-- #10 Array.each at inspec/lib/inspec/cli.rb:283
#11 Inspec::InspecCLI.exec(*targets#Array) at inspec/lib/inspec/cli.rb:283
When run method of the runner gets called, it loads control [file](https://github.com/inspec/inspec/blob/master/lib/inspec/profile_context.rb#L151) which instantiates the control_eval_context object [here](https://github.com/inspec/inspec/blob/master/lib/inspec/profile_context.rb#L61) and creates dsl, and the adds profile_context as dsl class methods [here](https://github.com/inspec/inspec/blob/master/lib/inspec/profile_context.rb#L243)
#0 Inspec::ProfileContext::DomainSpecificLunacy::ClassMethods.add_methods(profile_context#Inspec::ProfileContext) at /inspec/lib/inspec/profile_context.rb:242
#1 block in #<Class:Inspec::ProfileContext::DomainSpecificLunacy>.block in create_dsl(profile_context#Inspec::ProfileContext) at /inspec/lib/inspec/profile_context.rb:220
ͱ-- #2 Module.initialize at inspec/lib/inspec/profile_context.rb:218
ͱ-- #3 Class.new(*args) at inspec/lib/inspec/profile_context.rb:218
#4 #<Class:Inspec::ProfileContext::DomainSpecificLunacy>.create_dsl(profile_context#Inspec::ProfileContext) at inspec/lib/inspec/profile_context.rb:218
#5 Inspec::ProfileContext.to_resources_dsl at inspec/lib/inspec/profile_context.rb:56
#6 Inspec::ProfileContext.control_eval_context at inspec/lib/inspec/profile_context.rb:63
#7 Inspec::ProfileContext.load_control_file(*args#Array) at inspec/lib/inspec/profile_context.rb:154
#8 block in Inspec::Profile.block in collect_tests(include_list#Array) at inspec/lib/inspec/profile.rb:222
ͱ-- #9 Hash.each at inspec/lib/inspec/profile.rb:216
#10 Inspec::Profile.collect_tests(include_list#Array) at inspec/lib/inspec/profile.rb:216
#11 block in Inspec::Runner.block in load at inspec/lib/inspec/runner.rb:119
ͱ-- #12 Array.each at inspec/lib/inspec/runner.rb:101
#13 Inspec::Runner.load at inspec/lib/inspec/runner.rb:101
#14 Inspec::Runner.run(with#NilClass) at inspec/lib/inspec/runner.rb:135
#15 Inspec::InspecCLI.exec(*targets#Array) at inspec/lib/inspec/cli.rb:286
## Each file's contents are instance eval'd against the control_eval_context
### DSL methods are executed at this time
So, if you have a control file with `title` in it, that will call the title method that was defined at `lib/inspec/control_eval_context.rb:60`. Importantly, this also includes the `control` DSL keyword, and also the `describe` keyword (used for bare describes).
So, if you have a control file with `title` in it, that will call the title method that was defined [here](https://github.com/inspec/inspec/blob/master/lib/inspec/control_eval_context.rb#L46). Importantly, this also includes the `control` DSL keyword, and also the `describe` keyword (used for bare describes).
### Each control and their block are wrapped in an anonymous class
### Each control get registered as rule.
The anonymous class generator is located at `lib/inspec/control_eval_context.rb:24`. At this point, the terminology switches from `control` to `rule`. Each context class inherits from Inspec::Rule, which provides the constructor.
Each control gets registerd and the terminology switches from `control` to `rule` [here](https://github.com/inspec/inspec/blob/master/lib/inspec/control_eval_context.rb#L57)
The control context class also gets extended with the resource DSL, so anything in the source code for the control can use the resource DSL. This includes all resource names, but importantly, the `describe` DSL keyword.
@ -40,7 +62,7 @@ Finally, Inspec::Rule provides the control DSL - impact, title, desc, ref, and t
### The block is instance_eval'd against the control context class
See `lib/inspec/rule.rb:50`. We're now in two levels of instance eval'ing - the file is gradually being eval'd against the profile context anonymous class, and the current control's block is being instance eval'd against a control context anonymous class.
See `https://github.com/inspec/inspec/blob/master/lib/inspec/rule.rb#L46`. We're now in two levels of instance eval'ing - the file is gradually being eval'd against the profile context and the current control's block is being instance eval'd against a control context.
At this stage, control-level metadata (impact, title, refs, tags, desc) are evaluated and set as instance vars on the control.
@ -54,9 +76,9 @@ And, the describe and describe.one blocks are executed.
Using the method register_control (dynamically defined on the control eval context), we check for various skip conditions. If none of them apply, the control is then registered with the profile context using register_rule.
ProfileContext.register_rule's main job is to determine the full ID of the control (within the context of the profile) and either add it to the controls list, or (if another control with the same ID exists), merge it. (This is where overriding happens).
[ProfileContext.register_rule's](https://github.com/inspec/inspec/blob/master/lib/inspec/profile_context.rb#L183) main job is to determine the full ID of the control (within the context of the profile) and either add it to the controls list, or (if another control with the same ID exists), merge it. (This is where overriding happens).
Note: can skip a control with:
Inspec::Rule.set_skip_rule(control, msg)
## What else?
## What else?

View file

@ -40,7 +40,7 @@ class Thing < Inspec.resource(1)
filter_table_config.install_filter_methods_on_resource(self, :fetch_data)
def fetch_data
# This method should return an array of hashes - the raw data. We'll hardcode it here.
# This method should return an array of hashes - the raw data. We'll hard code it here.
[
{ thing_id: 1, color: :red },
{ thing_id: 2, color: :blue, tackiness: 'very' },
@ -301,7 +301,7 @@ This method behaves just like `thing_ids`, except that it returns the values of
You also get this for `thing_ids`. This is unrelated to `style: :simple` for `colors`.
People definitely use this in the wild. It reads badly to me; I think this is a legacy usage that we should consider deprecating. To me, this seems to imply that there is a sub-resource (here, colors) we are auditing. At least two core resouces (`xinetd_conf` and `users`) advocate this as their primary use.
People definitely use this in the wild. It reads badly to me; I think this is a legacy usage that we should consider deprecating. To me, this seems to imply that there is a sub-resource (here, colors) we are auditing. At least two core resources (`xinetd_conf` and `users`) advocate this as their primary use.
```ruby
# Filter on colors

View file

@ -0,0 +1,55 @@
# About `inspec init plugin` CLI command
## Purpose
`inspec init plugin` generates the scaffold of InSpec plugin, which can extend the functionality of InSpec itself.
## Operational Notes
### Generating InSpec Plugin
`inspec init plugin --help`
```
Usage:
inspec init plugin PLUGIN_NAME [options]
Options:
[--prompt], [--no-prompt] # Interactively prompt for information to put in your generated plugin.
# Default: true
[--detail=DETAIL] # How detailed of a plugin to generate. 'full' is a normal full gem with tests; 'core' has tests but no gemspec; 'test-fixture' is stripped down for a test fixture.
# Default: full
[--author-email=AUTHOR_EMAIL] # Author Email for gemspec
# Default: you@example.com
[--author-name=AUTHOR_NAME] # Author Name for gemspec
# Default: Your Name
[--description=DESCRIPTION] # Multi-line description of the plugin
[--summary=SUMMARY] # One-line summary of your plugin
# Default: A plugin with a default summary
[--license-name=LICENSE_NAME] # The name of a license
# Default: Apache-2.0
[--activator=one two three] # A list of plugin activator, in the form type1:name1, type2:name2, etc
# Default: ["cli_command:my_command"]
[--hook=one two three] # Legacy name for --activator - Deprecated.
[--homepage=HOMEPAGE] # A URL for your project, often a GitHub link
[--module-name=MODULE_NAME] # Module Name for your plugin package. Will change plugin name to CamelCase by default.
[--copyright=COPYRIGHT] # A copyright statement, to be added to LICENSE
[--log-level=LOG_LEVEL] # Set the log level: info (default), debug, warn, error
[--log-location=LOG_LOCATION] # Location to send diagnostic log messages to. (default: $stdout or Inspec::Log.error)
Generates an InSpec plugin, which can extend the functionality of InSpec itself.
```
### Options
`inspec init plugin` command requires few details about the plugin to be added. This can be added using command line prompt or by passing them as the options like for e.g `--author-name`,`--author-email`, `--description`, `--module-name`, etc.
`--detail` This option can be used to skip generation of test files or gemspec file. Available values `full`, `core` or `test-fixture`.
`--activator` Available activator type are `cli_command` and `reporter`. The default activator type is "cli_command".
Usage: `inspec init pluign <inspec-plugin-name> --activator "cli_command:my_test"`
`OR`
`inspec init plugin <inspec-plugin-reporter-name> --activator "reporter:my_reporter"`
**Note:** The InSpec plugin generator can currently only generate one activator of each type.
`--hook` Legacy name for `--activator` - Deprecated.

View file

@ -2,7 +2,7 @@
## Introduction
Chef InSpec uses Test Kitchen for its integration testing. Our current testing uses Docker as our backend. You should install and have Docker running befor you run any tests.
Chef InSpec uses Test Kitchen for its integration testing. Our current testing uses Docker (kitchen-dokken) as our backend. You should install and have Docker running before you run any tests.
### How to run specific integrations
@ -23,8 +23,6 @@ bundle exec rake test:integration[default-ubuntu-1604]
We run the test/integration/default profile at the end of each integration test in the verify stage. This confirms that our current code is compatible with test kitchen.
### Audit Testing
### Why no audit cookbook testing?
For Audit cookbook testing Chef InSpec sets up some special hooks. The integration rake command will bundle up the current checkout into a gem which is passed along to test kitchen in the os_prepare cookbook. When this cookbook is run it will install the local inspec gem. Audit will then use this gem accordingly when running in the post chef-client validators. The .kitchen.yml is setup to export the audit report to a json file which we look for and confirm the structure in the test/integration/default/controls/audit_spec.rb file.
In the validation file we confirm that the file was created from audit and that the structure looks correct. We also validate that the inspec ran with audit is the same that the current branch is using. This validates that audit did not use a older version for some reason.
Audit cookbook testing is handled in the audit cookbook repo. In addition, the audit cookbook restricts which InSpec gem can be installed, forcing the installation from Rubygems for Chef clients 15+. Since we need to test with the from-source inspec gem, we can't use that approach. Instead, we don't test using audit cookbook here.

View file

@ -18,4 +18,5 @@ image=chef:
CHANNEL: unstable
annotations:
tags:
- expeditor:final-channel-tags={{major}},{{major}}.{{minor}}
- expeditor:default-tags={{channel}}
- expeditor:final-channel-tags=latest,{{major}},{{major}}.{{minor}}

View file

@ -14,7 +14,7 @@ serve: chef_web_docs
chef_web_docs:
if [ -d "chef-web-docs/" ]; then \
pushd chef-web-docs && git reset HEAD --hard; git pull origin master && popd; \
pushd chef-web-docs && git reset HEAD --hard; git clean -fd; git pull --ff-only origin master; rm -rf public && popd; \
else \
git clone https://github.com/chef/chef-web-docs.git; \
fi

View file

@ -52,7 +52,7 @@ before the next promotion.
## Local Development Environment
We use [Hugo](https://gohugo.io/), [Go](https://golang.org/), and[NPM](https://www.npmjs.com/)
to build the Chef Documentation website. You will need Hugo 0.78.1 or higher
to build the Chef Documentation website. You will need Hugo 0.83.1 or higher
installed and running to build and view our documentation properly.
To install Hugo, NPM, and Go on Windows and macOS:

View file

@ -96,6 +96,8 @@ This subcommand has additional options:
Specifies the bastion user if applicable
* ``--config=CONFIG``
Read configuration from JSON file (`-` reads from stdin).
* ``--docker-url``
Provides path to Docker API endpoint (Docker).
* ``--enable-password=ENABLE_PASSWORD``
Password for enable mode on Cisco IOS devices.
* ``--format=FORMAT``
@ -146,7 +148,7 @@ This subcommand has additional options:
Specify which transport to use, defaults to negotiate (WinRM).
* ``--winrm-shell-type=WINRM_SHELL_TYPE``
Specify which shell type to use (powershell,elevated or cmd), defaults to powershell (WinRM).
## env
Output shell-appropriate completion configuration
@ -163,9 +165,9 @@ inspec env
Run all test files at the specified locations.
loads the given profile(s) and fetches their dependencies if needed. then
The subcommand loads the given profiles, fetches their dependencies if needed, then
connects to the target and executes any controls contained in the profiles.
one or more reporters are used to generate output.
One or more reporters are used to generate the output.
```
exit codes:
@ -178,57 +180,63 @@ exit codes:
172 chef license not accepted
```
below are some examples of using `exec` with different test locations:
Below are some examples of using `exec` with different test locations:
automate:
Chef Automate:
```
inspec compliance login
inspec automate login
inspec exec compliance://username/linux-baseline
```
supermarket:
`inspec compliance` is a backwards compatible alias for `inspec automate` and works the same way:
```
inspec compliance login
```
Chef Supermarket:
```
inspec exec supermarket://username/linux-baseline
```
local profile (executes all tests in `controls/`):
Local profile (executes all tests in `controls/`):
```
inspec exec /path/to/profile
```
local single test (doesn't allow inputs or custom resources)
Local single test (doesn't allow inputs or custom resources):
```
inspec exec /path/to/a_test.rb
```
git via ssh
Git via SSH:
```
inspec exec git@github.com:dev-sec/linux-baseline.git
```
git via https (.git suffix is required):
Git via HTTPS (.git suffix is required):
```
inspec exec https://github.com/dev-sec/linux-baseline.git
```
private git via https (.git suffix is required):
Private Git via HTTPS (.git suffix is required):
```
inspec exec https://api_token@github.com/dev-sec/linux-baseline.git
```
private git via https and cached credentials (.git suffix is required):
Private Git via HTTPS and cached credentials (.git suffix is required):
```
git config credential.helper cache
git ls-remote https://github.com/dev-sec/linux-baseline.git
inspec exec https://github.com/dev-sec/linux-baseline.git
```
web hosted fileshare (also supports .zip):
Web-hosted file (also supports .zip):
```
inspec exec https://webserver/linux-baseline.tar.gz
```
web hosted fileshare with basic authentication (supports .zip):
Web-hosted file with basic authentication (supports .zip):
```
inspec exec https://username:password@webserver/linux-baseline.tar.gz
```
@ -258,6 +266,8 @@ This subcommand has additional options:
Specifies the bastion port if applicable
* ``--bastion-user=BASTION_USER``
Specifies the bastion user if applicable
* ``--command-timeout=SECONDS``
Maximum seconds to allow a command to run.
* ``--config=CONFIG``
Read configuration from JSON file (`-` reads from stdin).
* ``--controls=one two three``
@ -266,8 +276,12 @@ This subcommand has additional options:
Write out a lockfile based on this execution (unless one already exists)
* ``--distinct-exit``, ``--no-distinct-exit``
Exit with code 101 if any tests fail, and 100 if any are skipped (default). If disabled, exit 0 on skips and 1 for failures.
* ``--docker-url``
Provides path to Docker API endpoint (Docker). Defaults to unix:///var/run/docker.sock on Unix systems and tcp://localhost:2375 on Windows.
* ``--enable-password=ENABLE_PASSWORD``
Password for enable mode on Cisco IOS devices.
* ``--filter-empty-profiles``, ``--no-filter-empty-profiles``
Filter empty profiles (profiles without controls) from the report.
* ``--host=HOST``
Specify a remote host which is tested.
* ``--input=name1=value1 name2=value2``
@ -292,6 +306,8 @@ This subcommand has additional options:
Enable one or more output reporters: cli, documentation, html, progress, json, json-min, json-rspec, junit, yaml
* ``--reporter-backtrace-inclusion``, ``--no-reporter-backtrace-inclusion``
Include a code backtrace in report data (default: true)
* ``--reporter-include-source``
Include full source code of controls in the CLI report
* ``--reporter-message-truncation=REPORTER_MESSAGE_TRUNCATION``
Number of characters to truncate failure messages in report data to (default: no truncation)
* ``--self-signed``, ``--no-self-signed``
@ -320,6 +336,8 @@ This subcommand has additional options:
Simple targeting option using URIs, e.g. ssh://user:pass@host:port
* ``--target-id=TARGET_ID``
Provide a ID which will be included on reports
* ``--tags=one two three``
A list of tags, a list of regular expressions that match tags, or a hash map where each value is a tag. `exec` will run controls referenced by the listed or matching tags.
* ``--user=USER``
The login user for a remote scan.
* ``--vendor-cache=VENDOR_CACHE``
@ -367,6 +385,8 @@ This subcommand has additional options:
Save the created profile to a path
* ``--profiles-path=PROFILES_PATH``
Folder which contains referenced profiles.
* ``--tags=one two three``
A list of tags that reference certain controls. Other controls are ignored.
* ``--vendor-cache=VENDOR_CACHE``
Use the given path for caching dependencies. (default: ~/.inspec/cache)
@ -420,12 +440,16 @@ This subcommand has additional options:
Specifies the bastion user if applicable
* ``-c``, ``--command=COMMAND``
A single command string to run instead of launching the shell
* ``--command-timeout=SECONDS``
Maximum seconds to allow a command to run.
* ``--config=CONFIG``
Read configuration from JSON file (`-` reads from stdin).
* ``--depends=one two three``
A space-delimited list of local folders containing profiles whose libraries and resources will be loaded into the new shell
* ``--distinct-exit``, ``--no-distinct-exit``
Exit with code 100 if any tests fail, and 101 if any are skipped but none failed (default). If disabled, exit 0 on skips and 1 for failures.
* ``--docker-url``
Provides path to Docker API endpoint (Docker). Defaults to unix:///var/run/docker.sock on Unix systems and tcp://localhost:2375 on Windows.
* ``--enable-password=ENABLE_PASSWORD``
Password for enable mode on Cisco IOS devices.
* ``--host=HOST``

View file

@ -30,7 +30,7 @@ Let's look at some simple examples.
### Singular Resource Example
```inspec
```ruby
describe car(owner: 'Tony Clifton') do
it { should exist }
its('license_plate') { should cmp 'MOONMAN' }
@ -73,7 +73,7 @@ _should\_not_ indicates this is a negated test. So, this test passes if the matc
### Plural Resource Example
```inspec
```ruby
describe cars.where(color: /^b/) do
it { should exist }
its('manufacturers') { should include 'Cadillac' }
@ -113,35 +113,35 @@ _'Cadillac'_ is an [expected result](#expected-result). Some matchers take an ex
#### its('count') { should _be >=_ 10 }
_be >=_ is an [operator matcher](#operator matcher). It allows you to perform numeric comparisons. All plural resources have a `count` property.
_be >=_ is an [operator matcher](#operator-matcher). It allows you to perform numeric comparisons. All plural resources have a `count` property.
## Text Glossary
### attribute
### Attribute
Deprecated name for [input](#input).
### control
### Control
### control block
### Control Block
The _`control`_ keyword is used to declare a _`control block`_. Here, the word 'control' means a 'regulatory control, recommendation, or requirement' - not a software engineering construct. A `control block` has a name (which usually refers to the assigned ID of the regulatory recommendation it implements), metadata such as descriptions, references, and tags, and finally groups together related [describe blocks](#describe-block) to implement the checks.
### core resource
### Core Resource
A [resource](#resource) that is included with InSpec; you are not required to install additional [plugins](#plugin) or depend on a [resource pack](#resource pack) to use the resource.
A [resource](#resource) that is included with InSpec; you are not required to install additional [plugins](#plugin) or depend on a [resource pack](#resource-pack) to use the resource.
### custom resource
### Custom Resource
A [resource](#resource) that is _not_ included with InSpec. It may be a resource of your own creation, or one you obtain by depending on a [resource pack](#resource pack).
A [resource](#resource) that is _not_ included with InSpec. It may be a resource of your own creation, or one you obtain by depending on a [resource pack](#resource-pack).
### describe
### Describe
### describe block
### Describe Block
The _`describe`_ keyword is used with a _`describe block`_ to refer to a Chef InSpec resource. You use the `describe` keyword along with the name of a [resource](#resource) to enclose related [tests](#test) that apply to the resource. Multiple describe blocks are usually grouped together in a [control](#control), but you can also use them outside of a control.
```Ruby
```ruby
control 'Rule 1.1 - Color restrictions' do
# Count only blue cars
describe cars.where(color: 'blue') do
@ -156,19 +156,19 @@ _DSL_ is an acronym for _Domain Specific Language_. It refers to the language ex
For [custom resource](#custom-resource) authors, an additional DSL is available - see the [Resource DSL page](/inspec/dsl_resource/).
### expected result
### Expected Result
When using a [matcher](#matcher), the _`expected result`_ is the value the matcher will compare against the [property](#property) being accessed.
In this example, the [`cmp`](/inspec/matchers/#cmp) matcher is being used to compare the `color` property to the expected result 'black'.
```Ruby
```ruby
describe car(owner: 'Bruce Wayne') do
its('color') { should cmp 'black' }
end
```
### filter statement
### Filter Statement
When using a [plural resource](#plural-resource), a _`filter statement`_ is used to select individual test subjects using [filter criteria](#filter-criteria). A filter statement almost always is indicated by the keyword `where`, and may be repeated using method chaining.
@ -176,16 +176,16 @@ A filter statement may use method call syntax (which allows basic criteria opera
In this example, `where(...)` is the filter statement.
```Ruby
```ruby
# Count only blue cars
describe cars.where(color: 'blue') do
its('count') { should eq 20 }
end
```
### filter criterion
### Filter Criterion
### filter criteria
### Filter Criteria
When using a [plural resource](#plural-resource), a _`filter criterion`_ is used to select individual test subjects within a [filter statement](#filter-statement). You may use multiple _`filter criteria`_ in a single filter statement.
@ -193,7 +193,7 @@ When method-call syntax is used with the filter statement, you provide filter cr
Here, `(color: blue)` is a single filter criterion being used with a filter statement in method-call syntax.
```Ruby
```ruby
# Count only blue cars
describe cars.where(color: 'blue') do
its('count') { should eq 20 }
@ -204,14 +204,14 @@ When block-method syntax is used with the filter statement, you provide a block.
Here, `{ engine_cylinders >= 6 }` is a block-syntax filter statement referring to one filter criterion.
```Ruby
```ruby
# Vroom!
describe cars.where { engine_cylinders >= 6 } do
its('city_mpg_ratings') { should_not include '4-star' }
end
```
### input
### Input
An _`input`_ is a value that Chef InSpec can source from a number of providers, including from the command line, profile metadata, or within the control file DSL itself. You can use this feature either to change a [profile's](#profile) behavior by passing different attribute files or to store secrets that should not be directly present in a profile.
@ -221,7 +221,7 @@ The CLI syntax for inputs is documented under the [`inspec exec`](/inspec/cli/#e
Inputs are documented in detail in the [input documentation](/inspec/inputs/).
### it
### It
Within a [describe block](#describe), _`it`_ declares an individual [test](#test) directly against the [resource](#resource) (as opposed to testing against one of the resource's [properties](#property), as [its](#its) does). Though it is possible to use [universal matchers](#universal-matcher) with `it`, it is much more typical to use [resource-specific matchers](#resource-specific-matchers).
@ -229,13 +229,13 @@ Within a [describe block](#describe), _`it`_ declares an individual [test](#test
Here, `it { should ... }` declares a test, calling the `classy?` matcher on Tony Clifton's car.
```Ruby
```ruby
describe car(owner: 'Tony Clifton') do
it { should be_classy }
end
```
### its
### Its
Within a [describe block](#describe), _`its`_ declares an individual [test](#test) against a property of the [resource](#resource) (as opposed to testing directly against the resource itself, as [it](#it) does). You must use [universal matchers](#universal-matcher) with `its`; you cannot use [resource-specific matchers](#resource-specific-matchers).
@ -245,7 +245,7 @@ The property to access is passed as a single string argument to `its`. As an adv
Here, `its('fuzzy_dice') { should ... }` declares a test, testing against the `fuzzy_dice` property of Tony Clifton's car. Let's assume - Tony being Tony - that `fuzzy_dice` will return an Array.
```Ruby
```ruby
describe car(owner: 'Tony Clifton') do
its('fuzzy_dice') { should_not be_empty }
its('fuzzy_dice.count') { should be >= 2 }
@ -253,7 +253,7 @@ describe car(owner: 'Tony Clifton') do
end
```
### matcher
### Matcher
A _`matcher`_ performs the actual assertions against [resources](#resource) or the [properties](#property) of resources. Matchers always return a true/false value. Matchers fall into two camps:
@ -266,13 +266,33 @@ For information on how RSpec matchers are related o Chef InSpec matchers, see [C
Here, `be_classy` is a resource-specific matcher operating directly on the `car`, while `cmp` is a universal matcher operating on the `manufacturer` property.
```Ruby
```ruby
describe car(owner: 'Tony Clifton') do
it { should be_classy }
its('manufacturer') { should cmp 'Cadillac' }
end
```
### Operator Matcher
An operator matcher allows you to use operators to compare numerical [expected results](#expected-result) against a [property](#property). All plural resources have a `count` property.
For example:
```ruby
describe cars do
its('count') { should be >= 10 }
end
```
Operators include:
- `==`
- `>=`
- `<=`
- `>`
- `<`
### plural resource
A _`plural resource`_ is a [resource](#resource) that specializes in performing searches and represents multiple occurrences of the resource on the [target](#target) platform. Plural resources are used to audit counts, inspect group properties, and have the unique ability to enforce negative tests ("nothing like this should exist") often required by compliance standards. Plural resources are not intended to perform in-depth auditing of an individual; use [singular resources](#singular-resource) for that.
@ -283,7 +303,7 @@ Plural resources support [filter statements](#filter-statement). See the [resour
Here, `cars` is a plural resource.
```Ruby
```ruby
describe cars.where(color: 'blue') do
its('count') { should eq 20 }
its('license_plates') { should include 'AUTOAZUL' }
@ -297,7 +317,7 @@ describe cars.where(color: 'blue') do
end
```
### profile
### Profile
A _`profile`_ is a set of related [controls](#control) in a distributable form. You might have a locally-developed profile that your organization uses to define baseline security on all machines, or you might use a pre-defined profile that implements the requirements of a specific compliance standard. For full details about the capabilities of a profile, see the [profile documentation](/inspec/profiles/).
@ -305,7 +325,7 @@ Profiles may be distributed locally as a directory tree, as a tarball or zipfile
Aside from controls, profiles can also contain [custom resources](#custom-resource). If the profile contains only custom resources and no controls, we call it a [resource pack](#resource-pack).
### property
### Property
A fact about a [resource](#resource). Typically, you use the [its](#its) keyword to access the property and write a [test](#test) within a [describe block](#describe-block), and then use a [universal matcher](#universal-matcher) to make assertions about the value of the property.
@ -313,17 +333,17 @@ Each resource has different properties. See the [resource documentation](/inspec
Here, `manufacturer` is a property of the `car` resource.
```Ruby
```ruby
describe car(owner: 'Tony Clifton') do
its('manufacturer') { should cmp 'Cadillac' }
end
```
### reporter
### Reporter
An output format for the `inspec exec` command line. Several reporters are available, including JSON and JUnit; see the [inspec exec documentation](/inspec/cli/#exec).
### resource
### Resource
A _`resource`_ represents a category of things on the [target](#target) you wish to examine. For example, to check for the existence and permissions of a file, you would use the [`file`](/inspec/resources/file/) resource. Chef InSpec offers dozens of different resources, from the highly specialized (such as `aws_security_group`, which examines firewall rules in AWS) to the very general (such as `command`, which runs a command and lets you examine its output).
@ -333,17 +353,17 @@ Resources are used within a [describe block](#describe-block) to perform [tests]
Here, `car` is a resource.
```Ruby
```ruby
describe car(owner: 'Tony Clifton') do
it { should be_classy }
end
```
### resource pack
### Resource Pack
A _resource pack_ is a type of [profile](#profile) that is used to distribute [custom resources](#custom-resource). This specialized type of profile contains no [controls](#control), but it does contain a `libraries` directory within which Ruby files define custom resources.
### resource parameter
### Resource Parameter
_`resource parameters`_ are information passed to the resource when they are declared. Typically, resource parameters provide identifying information or connectivity information. Resource parameters are not the same as a [filter statement](#filter-statement).
@ -351,39 +371,39 @@ Resource parameters vary from resource to resource; refer to the [resource docum
Here, `owner: 'Tony Clifton'` is a resource parameter.
```Ruby
```ruby
describe car(owner: 'Tony Clifton') do
it { should be_classy }
end
```
### resource-specific matcher
### Resource-Specific Matcher
A [matcher](#matcher) that operates directly on the [resource](#resource), as opposed to operating on a property as a [universal matcher](#universal matcher) does.
A [matcher](#matcher) that operates directly on the [resource](#resource), as opposed to operating on a property as a [universal matcher](#universal-matcher) does.
Resource-specific matchers often provide highly customized behavior. Check the [resource documentation](#/inspec/resources/) to discover which resource-specific matchers are available for your resource.
For example, the hypothetical `car` resource defines a `classy?` method, which is exposed as the `be_classy` matcher in Chef InSpec tests.
```Ruby
```ruby
describe car(owner: 'Tony Clifton') do
it { should be_classy }
end
```
### singular resource
### Singular Resource
A [resource](#resource) intended to uniquely identify a single object on the [target](#target). Singular resources specialize in providing richer auditing capabilities via resource-specific matchers. Compare to [plural resources](#plural-resource).
### target
### Target
The _`target`_ is the OS or API on which Chef InSpec is performing audits. In Chef InSpec 1.x, this was always an operating system target (a bare metal machine, VM, or container). In Chef InSpec 2.x and later, this can be an OS target, or an API target, including cloud providers such as AWS. Chef InSpec is agentless, meaning that the Chef InSpec code and profiles remain on your workstation, and the target is remotely interrogated without installing anything.
### test
### Test
A _`test`_ is an individual assertion about the state of the [resource](#resource) or one of its [properties](#property). All tests begin with the keyword [it](#it) or [its](#its). Tests are grouped within a [describe block](#describe-block).
### universal matcher
### Universal Matcher
A _universal matcher_ is a [matcher](#matcher) that can be used on the [properties](#property) of any type of [resource](#resource). For example, you can use the `cmp` matcher to check the value of properties without having to worry about Ruby type-casting. Universal matchers are almost always used with the [its](#its) keyword.
@ -391,7 +411,7 @@ Universal matchers are documented on the [Universal Matchers](/inspec/matchers/)
Here, we access the 'color' property, then use the `cmp` universal matcher to compare the property to the 'black' [expected result](#expected-result).
```Ruby
```ruby
describe car(owner: 'Bruce Wayne') do
its('color') { should cmp 'black' }
end

View file

@ -89,7 +89,6 @@ As installed (without specialized plugins), Chef InSpec supports several ways of
- Using the CLI option `--input name1=value1 name2=value2...` to read directly from the command line
- Using the CLI option `--input-file somefile.yaml` to read inputs from files
- In kitchen-inspec, using the `verifier/inputs` settings
- In the Audit Cookbook, using the `node[:audit][:inputs]`
In addition, Chef InSpec supports Input Plugins, which can provide optional integrations to specific key-value stores.
@ -99,7 +98,7 @@ In addition, Chef InSpec supports Input Plugins, which can provide optional inte
Briefly:
inline DSL < metadata < ( cli-input-file or kitchen-inspec or audit-cookbook ) < cli --input
inline DSL < metadata < ( cli-input-file or kitchen-inspec ) < cli --input
In addition, for inherited profiles:
@ -146,7 +145,6 @@ As packaged, Chef InSpec uses the following priority values:
| Metadata in a wrapper cookbook | 35 | Yes |
| CLI `--input-file` option | 40 | No |
| inspec-kitchen `inputs:` section | 40 | No |
| audit cookbook `node[:audit][:inputs]` | 40 | No |
| CLI `--input` option | 50 | No |
### What happened to "Attributes"?
@ -361,7 +359,7 @@ Inspec::InputRegistry.instance.cache_inputs = false
Required `String`. This option identifies the input.
Allowed in: All. When used in DSL and Metadata, the name is unique within the
current profile. When used in CLI input files, audit cookbook, and kitchen-inspec,
current profile. When used in CLI input files, and kitchen-inspec,
the input is copied across all profiles using the same name.
### Description
@ -418,6 +416,12 @@ input values that are used as test results.
Allowed in: Metadata
### Pattern
Optional, `Regexp`. This feature validates the input by matching it with the provided regular expression.
Allowed in: DSL, Metadata
## Advanced Topics
### Debugging Inputs with the Event Log

View file

@ -35,7 +35,7 @@ create an IAM user specifically for auditing activities.
#### Using Environment Variables to provide credentials
You may provide the credentials to Chef InSpec by setting the following environment
variables: `AWS_REGION`, `AWS_ACCESS_KEY_ID`, and `AWS_SECRET_KEY_ID`. You may
variables: `AWS_REGION`, `AWS_ACCESS_KEY_ID`, and `AWS_SECRET_ACCESS_KEY`. You may
also use `AWS_PROFILE`, or if you are using MFA, `AWS_SESSION_TOKEN`. See the
[AWS Command Line Interface Docs](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html)
for details.
@ -163,7 +163,7 @@ version is 3.0.25.
With a version of InSpec above 4.0.0, it is possible to create a profile with the
following command:
```
```bash
$ inspec init profile --platform gcp my-profile
Create new profile at /Users/me/my-profile
* Creating directory libraries
@ -171,15 +171,15 @@ Create new profile at /Users/me/my-profile
* Creating directory controls
* Creating file controls/example.rb
* Creating file inspec.yml
* Creating file attributes.yml
* Creating file inputs.yml
* Creating file libraries/.gitkeep
```
Assuming the attributes yml file contains your GCP project ID, this sample
Assuming the `inputs.yml` file contains your GCP project ID, this sample
profile can then be executed using the following command:
```
inspec exec my-profile --attrs my-profile/attributes.yml -t gcp://
```bash
inspec exec my-profile --input-file=my-profile/inputs.yml -t gcp://
```
#### Setting up the GCP Credentials File
@ -216,4 +216,4 @@ $ inspec detect -t gcp://
Name: gcp
Families: cloud, api
Release: google-cloud-v
```
```

View file

@ -35,11 +35,17 @@ suites:
and then run the following command:
```bash
inspec compliance login https://compliance.test --user admin --insecure --token ''
inspec automate login https://compliance.test --user admin --insecure --token ''
```
where `--insecure` is required when using self-signed certificates.
`inspec compliance` is a backwards compatible alias for `inspec automate` and works the same way:
```bash
inspec compliance login https://compliance.test --user admin --insecure --token ''
```
Use a compliance profile from the Chef Supermarket:
```YML

View file

@ -90,6 +90,35 @@ Output cli to screen and write json to a file.
}
}
```
## Reporter Options
The following are CLI options that may be used to modify reporter behavior. Many of these options allow you to limit the size of the report, because some reporters (such as the json-automate reporter) have a limit on the total size of the report that can be processed.
`--diff`, `--no-diff`
: Include a `diff` comparison of textual differences in failed test output (default: `true`).
: Use `--no-diff` to limit the size of the report output when tests contain large amounts of text output.
`--filter-empty-profiles`
: Remove empty profiles (those containing zero controls, such as resource packs) from the output of the reporter.
`--reporter-backtrace-inclusion`, `--no-reporter-backtrace-inclusion`
: Include a code backtrace in report data (default: `true`).
: The `--no-reporter-backtrace-inclusion` option may be used to limit report size when large code stack traces are present in the output.
`--reporter-include-source`
: (CLI reporter only) Include full source code of controls in the report.
`--reporter-message-truncation=N`
: Number of characters to truncate failure messages in report data (default: no truncation).
: This may be used to limit the size of reports when failure messages are exceptionally large.
## Supported Reporters
@ -101,7 +130,23 @@ This is the basic text base report. It includes details about which tests passed
### json
This reporter includes all information about the profiles and test results in standard json format.
This reporter includes all information about the profiles and test results in standard JSON format. You may optionally pass through arbitrary structured JSON data by setting a JSON configuration with the `--config` parameter.
For example:
```json
{
"reporter": {
"json": {
"stdout": true,
"passthrough": {
"a": 1,
"b": false
}
}
}
}
```
### json-min

View file

@ -19,6 +19,10 @@ Use the `apache_conf` Chef InSpec audit resource to test the configuration setti
This resource is distributed along with Chef InSpec itself. You can use it automatically.
### Requirements
`ServerRoot` should be included in a apache conf file. If not present the included configs will not be accessible to the resource.
### Version
This resource first became available in v1.0.0 of InSpec.

View file

@ -41,7 +41,7 @@ where
This matcher will match any property listed in the `auditd.conf` configuration file. Property names and expected values are case-insensitive:
- `admin_space_left`, `admin_space_left_action`, `action_mail_acct`, `disk_error_action`, `disk_full_action`, `flush`, `freq`, `log_file`, `log_format`, `max_log_file`, `max_log_file_action`, `num_logs`, `space_left`, `space_left_action`
- `admin_space_left`, `admin_space_left_action`, `action_mail_acct`, `conf_path`, `content`, `disk_error_action`, `disk_full_action`, `flush`, `freq`, `log_file`, `log_format`, `max_log_file`, `max_log_file_action`, `num_logs`, `params`, `space_left`, `space_left_action`
## Property Examples
@ -66,6 +66,10 @@ The following examples show how to use this Chef InSpec audit resource.
its('disk_error_action') { should cmp 'halt' }
end
describe file(auditd_conf.conf_path) do
its('group') { should cmp 'root' }
end
## Matchers
For a full list of available matchers, please visit our [matchers page](/inspec/matchers/).

View file

@ -6,8 +6,8 @@ platform = "aws"
[menu]
[menu.inspec]
title = "aws_ecr_image Resource"
identifier = "inspec/resources/aws/aws_ecr_image.md About the aws_ecr_image Resource"
title = "aws_ecr_image"
identifier = "inspec/resources/aws/aws_ecr_image"
parent = "inspec/resources/aws"
+++

View file

@ -6,8 +6,8 @@ platform = "aws"
[menu]
[menu.inspec]
title = "About the aws_internet_gateway Resource"
identifier = "inspec/resources/aws/aws_internet_gateway.md aws_internet_gateway"
title = "aws_internet_gateway"
identifier = "inspec/resources/aws/aws_internet_gateway"
parent = "inspec/resources/aws"
+++

View file

@ -50,7 +50,7 @@ _**If the current Account is the Master Account, the following properties are al
| ------------- | ------------------------------------------------------ |
| account_id | The ID of the current Account. |
| account_arn | The ARN of the current Account. |
| account_name | The Name of the current Acccount. |
| account_name | The Name of the current Account. |
| account_email | The Email address associated with the current Account. |
## Examples

View file

@ -52,7 +52,7 @@ See also the [AWS documentation on SNS](https://docs.aws.amazon.com/sns/latest/d
its('endpoint') { should cmp '+16105551234' }
# If protocol is 'email' or 'email-json', endpoint should be an email address
its('endpoint') { should cmp 'myemail@example.com' }
# If protocal is 'http', endpoint should be a URL beginning with 'https://'
# If protocol is 'http', endpoint should be a URL beginning with 'https://'
its('endpoint') { should cmp 'https://www.exampleurl.com' }
# If the protocol is 'lambda', its endpoint should be the ARN of a AWS Lambda function
its('endpoint') { should cmp 'rn:aws:lambda:us-east-1:account-id:function:myfunction' }

View file

@ -69,7 +69,7 @@ name and resource group.
## Parameter Examples
The resource group as well as the Activty Log Alert
The resource group as well as the Activity Log Alert
name.
describe azurerm_monitor_activity_log_alert(resource_group: 'example', name: 'AlertName') do

View file

@ -99,21 +99,21 @@ The default_security_rules property contains the set of Default Security Rules.
### allow_ssh_from_internet
The allow_ssh_from_internet property contains a boolean value determined by analysing
The allow_ssh_from_internet property contains a boolean value determined by analyzing
the Security Rules and Default Security Rules for unrestricted SSH access.
it { should_not allow_ssh_from_internet }
### allow_rdp_from_internet
The allow_rdp_from_internet property contains a boolean value determined by analysing
The allow_rdp_from_internet property contains a boolean value determined by analyzing
the Security Rules and Default Security Rules for unrestricted RDP access.
it { should_not allow_rdp_from_internet }
### allow\port_from_internet
The allow_port_from_internet property contains a boolean value determined by analysing
The allow_port_from_internet property contains a boolean value determined by analyzing
the Security Rules and Default Security Rules for unrestricted access to a specified port.
it { should_not allow_port_from_internet('443') }

View file

@ -75,11 +75,10 @@ The `params` matcher tests arbitrary parameters for the bonded network interface
describe bond('bond0') do
its('mode') { should eq 'IEEE 802.3ad Dynamic link aggregation' }
its('Transmit Hash Policy') { should eq 'layer3+4 (1)' }
its('MII Status') { should eq 'up' }
its('MII Polling Interval (ms)') { should eq '100' }
its('Up Delay (ms)') { should eq '0' }
its('Down Delay (ms)') { should eq '0' }
its('params') { should have_key 'Transmit Hash Policy' }
its('params') { should include 'Transmit Hash Policy' => 'layer3+4 (1)' }
its('params') { should have_key 'MII Status' }
its('params') { should include 'MII Status' => 'up' }
end
## Matchers

View file

@ -136,6 +136,30 @@ Wix includes several tools -- such as `candle` (preprocesses and compiles source
end
end
### Timing Out Long-Running Commands
On target platforms that support the feature, the command resource takes an optional `timeout:` parameter which specifies how long the command may run in seconds before erroring out and failing the control.
```ruby
describe command("find / -owner badguy", timeout: 300) do
its("stdout") { should be_empty }
end
```
This example would run the `find` command for up to 300 seconds, then give up and fail the control if it exceeded that time.
On supported target platforms, the default timeout is 3600 seconds (one hour).
Aside from setting the value on a per-resource basis, you may also use the `--command-timeout` CLI option to globally set a command timeout. The CLI option takes precedence over any per-resource `timeout:` options.
Currently supported target platforms include:
* Local Unix-like OSes, including macOS
* SSH targets
* Windows targets via WinRM
Any target platforms not listed are not supported at this time.
On unsupported platforms, the timeout value is ignored and the command will run indefinitely.
### Redacting Sensitive Commands
By default the command that is ran is shown in the Chef InSpec output. This can be problematic if the command contains sensitive arguments such as a password. These sensitive parts can be redacted by passing in `redact_regex` and a regular expression to redact. Optionally, you can use 2 capture groups to fine tune what is redacted.

View file

@ -25,12 +25,18 @@ This resource first became available in v1.15.0 of InSpec.
## Syntax
A `crontab` resource block declares a user (which defaults to the current user, if not specified), and then the details to be tested, such as the schedule elements for each crontab entry or the commands itself:
A `crontab` resource block declares a user (which defaults to the current user) and the details to be tested, such as the schedule elements for each crontab entry or the exact commands themselves:
describe crontab do
its('commands') { should include '/some/scheduled/task.sh' }
end
{{< note >}}
The `include` matcher in this context specifies the entire list of commands that the crontab should include and not a particular substring that should be included by a command. The `include` matcher always matches a complete command invocation, including options and arguments.
{{< /note >}}
The path to the system crontab can also be supplied via:
describe crontab(path: '/etc/cron.d/some_crontab') do
@ -46,7 +52,7 @@ The following examples show how to use this Chef InSpec audit resource.
### Test that root's crontab has a particular command
describe crontab('root') do
its('commands') { should include '/path/to/some/script' }
its('commands') { should include '/path/to/some/script -option arg' }
end
### Test that myuser's crontab entry for command '/home/myuser/build.sh' runs every minute

View file

@ -13,6 +13,13 @@ platform = "os"
Use the `group` Chef InSpec audit resource to test a single group on the system.
The `group` resource uses the following system groups:
- On **non-Windows** systems the group resource tests a local group defined in the`/etc/group` file.
- On **Windows** systems the group resource tests a local group defined by Local Users and Groups.
## Availability
### Installation
@ -62,6 +69,25 @@ The `members` property tests the members that belong to the group:
its('members') { should include 'root' }
where `members` returns:
- an array of group members for **Windows Platform**.
Example: `["member1", "member2"]`
- a CSV formatted string of group members for **Non-Windows Platforms**.
Example: `"member1,member2"`
### members_array
The `members_array` property tests the members that belong to a group just like the
`members` property,
but the value returned by this property is always an array of group members.
its('members_array') { should include 'root' }
## Matchers
For a full list of available matchers, please visit our [matchers page](/inspec/matchers/).

View file

@ -13,6 +13,12 @@ platform = "os"
Use the `groups` Chef InSpec audit resource to test multiple groups on the system.
The `groups` resource uses the following system groups:
- On **non-Windows** systems the group resource tests local groups defined in the`/etc/group` file.
- On **Windows** systems the group resource tests local groups defined by Local Users and Groups.
## Availability
### Installation
@ -74,6 +80,24 @@ The `members` property tests the members that belong to a group:
its('members') { should include 'root' }
its('members') { should include 'Administrator' }
where `members` returns:
- an array of group members for **Windows Platform**.
Example: `["member1", "member2"]`
- a single element array that contains a CSV string of group members for **Non-Windows Platforms**.
Example: `["member1,member2"]`
### members_array
The `members_array` property tests the group members just like the `members` property,
but the value returned by this property is always an array of group members.
its('members_array') { should include 'root' }
its('members_array') { should include 'Administrator' }
## Matchers
For a full list of available matchers, please visit our [matchers page](/inspec/matchers/).

View file

@ -0,0 +1,62 @@
+++
title = "mongodb_conf resource"
draft = false
gh_repo = "inspec"
platform = "os"
[menu]
[menu.inspec]
title = "mongodb_conf"
identifier = "inspec/resources/os/mongodb_conf.md mongodb_conf resource"
parent = "inspec/resources/os"
+++
Use the `mongodb_conf` Chef InSpec audit resource to test the contents of the configuration file for MongoDB, typically located at `/etc/mongod.conf` or `C:\Program Files\MongoDB\Server\<version>\bin\mongod.cfg`, depending on the platform.
## Availability
### Installation
This resource is distributed along with Chef InSpec itself. You can use it automatically.
## Syntax
A `mongodb_conf` resource block declares one (or more) settings in the `mongodb.conf` file, and then compares the setting in the configuration file to the value stated in the test:
describe mongodb_conf('path') do
its('setting') { should eq 'value' }
end
where
- `'setting'` specifies a setting in the `mongodb.conf` file
- `('path')` is the non-default path to the `mongodb.conf` file (optional)
- `should eq 'value'` is the value that is expected
## Examples
The following examples show how to use this Chef InSpec audit resource.
### Test the key management configuration options
describe mongodb_conf do
its(["security", "enableEncryption"]) { should eq true }
end
### Test the port on which MongoDB listens
describe mongodb_conf do
its(["net", "port"]) { should eq 27017 }
end
### Test the security configuration options
describe mongodb_conf do
its(["security", "authorization"]) { should eq "enabled" }
end
## Matchers
For a full list of available matchers, please visit our [matchers page](/inspec/matchers/).

View file

@ -0,0 +1,113 @@
+++
title = "mongodb_session resource"
draft = false
gh_repo = "inspec"
platform = "os"
[menu]
[menu.inspec]
title = "mongodb_session"
identifier = "inspec/resources/os/mongodb_session.md mongodb_session resource"
parent = "inspec/resources/os"
+++
Use the `mongodb_session` Chef InSpec audit resource to run MongoDB command against a MongoDB Database.
## Availability
### Installation
This resource is distributed along with Chef InSpec itself. You can use it automatically.
## Syntax
A `mongodb_session` resource block declares the `user`, `password`, and `database` to use for the session and then the command to be run:
describe mongodb_session(user: "username", password: "password", database: "test").query(key: value) do
its("params") { should match(/expected-result/) }
end
where
- `mongodb_session` declares a user, password, and database, connecting locally, with permission to run the query.
- `query` contains the query to be run.
- `its("params") { should eq(/expected-result/) }` compares the results of the query against the expected result in the test
### Optional Parameters
The `mongodb_session` InSpec resource accepts `user`, `password`, `host`, `port`, `auth_source`, `auth_mech`, `ssl`, `ssl_cert`, `ssl_ca_cert`, and `auth_mech_properties` parameters.
In Particular:
#### `host`
The server host IP address. Default value: `127.0.0.1`.
#### `port`
The server port. Default value: `27017`.
#### `auth_mech`
The authentication mechanism. The available options are: `:scram`, `:scram256`, `:mongodb_x509`, and `:aws`. Default value: `:scram`.
See the MongoDB documentation on [Ruby driver authentication](https://docs.mongodb.com/ruby-driver/current/reference/authentication/) for more information.
#### `auth_source`
The database where the users authentication credentials are stored. The default value is the database name that is passed as a parameter to the resource.
#### `ssl`
Whether to use the SSL security protocol or not. Set to `true` to use SSL transport, default value: `false`. See the MongoDB documentation on [Ruby Driver authentication](https://docs.mongodb.com/ruby-driver/current/reference/authentication/#client-certificate-x-509) for more information.
#### 'ssl_cert'
Path to the SSL certificate file.
#### `ssl_ca_cert`
Path to the SSL Certificate Authority (CA) certificate file.
#### `ssl_key`
Path to SSL key file.
#### `auth_mech_properties`
A hash of the authentication mechanism properties. This option is generally used with the AWS authentication mechanism. See the MongoDB documentation on [Ruby Driver authentication using AWS](https://docs.mongodb.com/ruby-driver/current/reference/authentication/#aws) for more information.
### MongodDB Query Reference Documentation
This resource uses the [MongoDB Ruby Driver](https://docs.mongodb.com/ruby-driver/current/reference/authentication/) to fetch the data.
## Examples
The following examples show how to use this Chef InSpec audit resource.
### Test the roles information using the `rolesInfo` command in MongoDB.
describe mongodb_session(user: "foo", password: "bar", database: "test").query(rolesInfo: "dbAdmin").params["roles"].first do
its(["role"]) { should eq "dbAdmin" }
end
### Test the MongoDB user role.
describe mongodb_session(user: "foo", password: "bar", database: "test").query(usersInfo: "foo").params["users"].first["roles"].first do
its(["role"]) { should eq "readWrite" }
end
### Test the database parameters.
describe mongodb_session(user: "foo", password: "bar", database: "test").query(rolesInfo: "dbAdmin") do
its("params") { should_not be_empty }
its("params") { should include "roles" }
end
## Matchers
For a full list of available matchers, please visit our [matchers page](/inspec/matchers/).
### params
The `params` contains all the query data.

View file

@ -0,0 +1,69 @@
+++
title = "opa_api resource"
draft = false
gh_repo = "inspec"
platform = "os"
[menu]
[menu.inspec]
title = "opa_api"
identifier = "inspec/resources/os/opa_api.md opa_api resource"
parent = "inspec/resources/os"
+++
Use the `opa_api` Chef InSpec audit resource to query Open Policy Agent (OPA) using the OPA URL and data.
## Availability
### Installation
This resource is distributed along with Chef InSpec itself. You can use it automatically.
## Syntax
An `opa_api` resource block declares OPA policy configurations that can be tested.
describe opa_api(url: "localhost:8181/v1/data/example/violation", data: "input.json") do
its(["result"]) { should eq 'value' }
end
where
- `'url'` specifies the url of the OPA server on which OPA is running.
- `'data'` specifies the json formatted data or json file.
- `its(["returned_result"]) { should eq 'expected_result' }` compares the results of the query against the expected result in the test.
## parameters
The `opa_api` resource InSpec resource requires a `url` and `data` as a JSON file or a string in JSON format.
### `url` _(required)_
The URL of the OPA API server.
### `data` _(required)_
An OPA query as a JSON data file or a string in JSON format.
## Examples
The following examples show how to use this Chef InSpec audit resource.
describe opa_api(url: "localhost:8181/v1/data/example/allow", data: "input.json") do
its(["result"]) { should eq true }
its("allow") { should eq "true" }
end
The above example shows how the `allow` value can be fetched in two ways.
## Matchers
For a full list of available matchers, please visit our [matchers page](/inspec/matchers/).
## Properties
### allow
The `allow` property checks if specific input is as per the policy defined in OPA. If `allow` is not defined in the policy file then this matcher will not work.
its('allow') { should eq 'value' }

View file

@ -0,0 +1,78 @@
+++
title = "opa_cli resource"
draft = false
gh_repo = "inspec"
platform = "os"
[menu]
[menu.inspec]
title = "opa_cli"
identifier = "inspec/resources/os/opa_cli.md opa_cli resource"
parent = "inspec/resources/os"
+++
Use the `opa_cli` Chef InSpec audit resource to query Open Policy Agent (OPA) using an OPA policy file, a data file, and a query.
## Availability
### Installation
This resource is distributed along with Chef InSpec itself. You can use it automatically.
## Syntax
An `opa_cli` resource block declares OPA policy configurations that can be tested.
describe opa_cli(policy: "example.rego", data: "input.json", query: "data.example.allow") do
its(["result"]) { should eq "value" }
end
where
- `data` specifies the json formatted input data or file path.
- `policy` the path to policy file.
- `query` specifies the query to be run.
- `its(["result"]) { should eq "value" }` compares the results of the query against the expected result in the test
## parameters
The `opa_cli` resource InSpec resource accepts `policy`, `data`, `query`, and `opa_executable_path` as parameters.
### `policy` _(required)_
The path to the OPA policy file.
### `data` _(required)_
An OPA query as a JSON data file or a string in JSON format.
### `query` _(required)_
The query to be evaluated against policy and input data.
### `opa_executable_path`
This is the full path to the OPA binary or EXE file used for running the OPA CLI or OPA commands. By default it will consider that the path is added in PATH variable.
## Examples
The following examples show how to use this Chef InSpec audit resource:
describe opa_cli(query: "data.example.allow", policy: "example.rego", data: "input.json", opa_executable_path: "./opa") do
its(["result", 0, "expressions", 0, "value"]) { should eq true }
its("allow") { should eq "true" }
end
The above example shows how the `allow` value can be fetched in two ways.
## Matchers
For a full list of available matchers, please visit our [matchers page](/inspec/matchers/).
## Properties
### allow
The `allow` property checks if specific input is as per the policy defined in OPA. If `allow` is not defined in the policy file then this matcher will not work.
its('allow') { should eq 'value' }

View file

@ -47,7 +47,7 @@ where
`address` returns a an array of strings that matches the where condition of the filter table
describe pg_ident_conf.where { pg_username == 'name' } do
describe postgres_ident_conf.where { pg_username == 'name' } do
its('map_name') { should eq ['value'] }
end
@ -55,7 +55,7 @@ where
`pg_username` returns a an array of strings that matches the where condition of the filter table
describe pg_ident_conf.where { pg_username == 'name' } do
describe postgres_ident_conf.where { pg_username == 'name' } do
its('pg_username') { should eq ['value'] }
end
@ -63,7 +63,7 @@ where
`system_username` returns a an array of strings that matches the where condition of the filter table
describe pg_ident_conf.where { pg_username == 'name' } do
describe postgres_ident_conf.where { pg_username == 'name' } do
its('system_username') { should eq ['value'] }
end

View file

@ -31,10 +31,15 @@ A `security_policy` resource block declares the name of a security policy and th
its('policy_name') { should eq 'value' }
end
describe security_policy(translate_sid: true) do
its('policy_name') { should include 'sid_name' }
end
where
- `'policy_name'` must specify a security policy
- `{ should eq 'value' }` tests the value of `policy_name` against the value declared in the test
- `translate_sid` converts the SID into human readable SID name if true. Default value is false.
## Examples

View file

@ -0,0 +1,173 @@
+++
title = "selinux resource"
draft = false
gh_repo = "inspec"
platform = "linux"
[menu]
[menu.inspec]
title = "selinux"
identifier = "inspec/resources/os/selinux.md selinux resource"
parent = "inspec/resources/os"
+++
Use the `selinux` Chef InSpec audit resource to test the configuration data of the SELinux policy, SELinux modules and SELinux booleans.
The `selinux` resource extracts and exposes data reported by the `sestatus`, `semodule -lfull`, and `semanage boolean -l -n` command.
## Availability
### Installation
This resource is distributed along with Chef InSpec itself. You can use it automatically.
### Version
This resource first became available in v4.35.1 of InSpec.
## Syntax
The `selinux` Chef InSpec resource block tests the state and mode of SELinux policy.
describe selinux do
it { should be_installed }
it { should_not be_disabled }
it { should be_enforcing }
it { should_not be_permissive }
end
The `selinux` resource block also allows you to write tests for multiple modules:
describe selinux.modules.where("zebra") do
it { should exist }
it { should be_installed }
it { should be_enabled }
end
or:
describe selinux.modules.where(status: "installed") do
it { should exist }
its('count') { should cmp 404 }
end
where:
- `.where()` specifies the parameter and expected value.
- `name`, `status`, `state`, and `priority` are valid parameters.
The `selinux` resource block also allows you to write tests for multiple booleans:
describe selinux.booleans.where(name: "httpd_enable_homedirs") do
it { should_not be_on }
end
or:
describe selinux.booleans.where(name: "xend_run_blktap", state: "on") do
it { should exist }
its('defaults') { should cmp "on" }
end
- `.where()` specifies the parameter and expected value.
- `name`, `state`, and `default` are valid parameters for `booleans`.
## Examples
The following examples show how to use this Chef InSpec selinux resource.
### Test if SELinux is installed and enabled
describe selinux do
it { should be_installed }
it { should_not be_disabled }
end
### Test if SELinux is enabled and running in enforcing mode
describe selinux do
it { should_not be_disabled }
it { should be_enforcing }
end
### Test the selinux policy type
describe selinux do
its('policy') { should eq "targeted"}
end
## Matchers
For a full list of available matchers, please visit our [matchers page](/inspec/matchers/).
### be_installed
The `be_installed` matcher tests if the SElinux policy or SElinux modules are installed on the system:
it { should be_installed }
### be_disabled
The `be_disabled` matcher tests if the SELinux is disabled on the system:
it { should be_disabled }
### be_enforcing
The `be_enforcing` matcher tests if the SELinux mode is set to enforcing:
it { should be_enforcing }
### be_permissive
The `be_permissive` matcher tests if the SELinux mode is set to permissive:
it { should be_permissive }
### be_on
The `be_on` matcher tests if the SELinux boolean is on:
it { should be_on }
### be_enabled
The `be_enabled` matcher tests if the SElinux module is enabled:
it { should be_enabled }
## Resource Parameters
- `names`, `status`, `states`, and `priorities` are valid parameters for SELinux policy modules.
- `names`, `status`, `states`, and `defaults` are valid parameters for SELinux `booleans`.
## Resource Parameter Examples
### modules
`modules` returns information about SELinux modules using the [semodule -lfull](https://man7.org/linux/man-pages/man8/semodule.8.html) command.
Note: The `semodule -l` command [does not provide version information](https://access.redhat.com/solutions/2760071) for newer versions of Linux-based systems like RHEL8 and Centos8, so we do not support that option.
```ruby
describe selinux.modules do
its("names") { should include "zebra" }
its("status") { should include "installed" }
its("states") { should include "enabled" }
its("priorities") { should include "100" }
end
```
### booleans
`booleans` returns information about SELinux booleans using the [semanage boolean -l -n](https://man7.org/linux/man-pages/man8/semanage-boolean.8.html) command.
```ruby
describe selinux.booleans do
its("names") { should include "httpd_enable_homedirs" }
its("states") { should include "on" }
its("states") { should include "off" }
its("defaults") { should include "on" }
its("defaults") { should include "off" }
end
```

View file

@ -25,7 +25,7 @@ This resource first became available in v1.0.0 of InSpec.
## Syntax
An `sshd_config` resource block declares the client OpenSSH configuration data to be tested:
An `sshd_config` resource block declares the OpenSSH daemon configuration data to be tested:
describe sshd_config('path') do
its('name') { should include('foo') }

View file

@ -0,0 +1,85 @@
+++
title = "toml resource"
draft = false
gh_repo = "inspec"
platform = "os"
[menu]
[menu.inspec]
title = "toml"
identifier = "inspec/resources/os/toml.md toml resource"
parent = "inspec/resources/os"
+++
Use the `toml` Chef InSpec audit resource to test settings in a TOML file.
## Availability
### Installation
This resource is distributed along with Chef InSpec itself. You can use it automatically.
### Version
This resource first became available in v1.0.0 of InSpec.
## Syntax
An `toml` resource block declares the configuration settings to be tested:
```ruby
describe toml('path') do
its('setting_name') { should eq 'value' }
end
```
where:
- `'setting_name'` is a setting key defined in the TOML file.
- `('path')` is the path to the TOML file.
- `{ should eq 'value' }` is the value that is expected.
## Examples
In the examples below, the `example.toml` file contains the following data:
```toml
port = 8080
fruits = ["apple", "banana", "cantaloupe"]
[section]
key1 = "value1"
```
**Verify the port number:**
```ruby
describe toml('path/to/example.toml') do
its('port') { should eq 8080 }
end
```
**Verify the value of an array using brackets:**
```ruby
describe toml('path/to/example.toml') do
its(['fruits', 0]) { should eq 'apple' }
end
```
**Verify the value of a key in a table using brackets:**
```ruby
describe toml('path/to/example.toml') do
its(['section', 'key1']) { should cmp 'value1' }
end
```
## Properties
This resource supports any of the settings listed in a TOML file as properties.
## Matchers
For a full list of available matchers, please visit our [matchers page](/inspec/matchers/).

View file

@ -11,7 +11,7 @@ platform = "linux"
parent = "inspec/resources/os"
+++
Use the `zfs_dataset` Chef InSpec audit resource to test the ZFS datasets on FreeBSD systems.
Use the `zfs_dataset` Chef InSpec audit resource to test the ZFS datasets on FreeBSD & Linux (Check [OS Family Details](https://docs.chef.io/inspec/resources/os/#osfamily-helpers) for more details).
## Availability

View file

@ -11,7 +11,7 @@ platform = "linux"
parent = "inspec/resources/os"
+++
Use the `zfs_pool` Chef InSpec audit resource to test the ZFS pools on FreeBSD systems.
Use the `zfs_pool` Chef InSpec audit resource to test the ZFS pools on FreeBSD & Linux (Centos, RHEL, Ubuntu, CloudLinux, Debian) systems.
## Availability

View file

@ -230,3 +230,49 @@ $ inspec shell --format json -c 'describe file("/Users/test") do it { should exi
}
}
```
## Running Chef InSpec Shell With Inputs
With InSpec [profiles that support inputs]({{< relref "inputs/#which-profiles-support-inputs" >}}),
you can set inputs using the InSpec `shell` command. This allows you to work more consistently with
InSpec profiles when switching between the `shell` and `exec` commands.
For more details on inputs, see the [inputs reference](/inspec/inputs/).
### Set Inputs with Command-line Options
The `shell` command accepts one or more inputs in the command line as single-quoted YAML or JSON structures.
```bash
$ inspec shell --input=input_name=input_value
Welcome to the interactive InSpec Shell
To find out how to use it, type: help
inspec> control 'my_control' do
inspec> describe input('input_name') do
inspec> it { should cmp 'input_value' }
inspec> end
inspec> end
Profile: inspec-shell
✔ my_control: input_value
✔ input_value is expected to cmp == "input_value"
Profile Summary: 1 successful control, 0 control failures, 0 controls skipped
Test Summary: 1 successful, 0 failures, 0 skipped
inspec> exit
```
### Set Inputs with YAML File
You can also save inputs and values to one or more YAML files and pass them to `shell` in the command line.
For example:
```yaml
input_name: input_value
another_input: another_value
```
```bash
inspec shell --input-file=<path>
```

View file

@ -0,0 +1,24 @@
+++
title = "Chef InSpec Troubleshooting"
draft = false
gh_repo = "inspec"
[menu]
[menu.inspec]
title = "Troubleshooting"
identifier = "inspec/Troubleshooting"
parent = "inspec"
weight = 55
+++
## Undefined Local Variable or Method Error for Cloud Resource
This error is a result of invoking a resource from one of the cloud resource packs without initializing an InSpec profile with that resource pack (AWS, Azure, or GCP) as a dependency.
InSpec profiles that use **any cloud resource** must have the resource pack defined as a dependency.
See the relevant resource pack readme for instructions:
- [inspec-aws README](https://github.com/inspec/inspec-aws#use-the-resources)
- [inspec-azure README](https://github.com/inspec/inspec-azure#use-the-resources)
- [inspec-gcp README](https://github.com/inspec/inspec-gcp#use-the-resources)

View file

@ -1,7 +1,7 @@
[build]
[build.environment]
HUGO_VERSION = "0.78.1"
HUGO_VERSION = "0.83.1"
HUGO_ENABLEGITINFO = "true"
GO_VERSION = "1.15"
NODE_ENV = "development"

View file

@ -120,6 +120,11 @@
"object_classes": {
"action": "warn",
"suffix": "These classes will be removed in InSpec 5.0."
},
"cli_option_hook":{
"action": "warn",
"prefix": "The --hook option is being replaced by the --activator option.",
"suffix": "This options will be removed in InSpec 4.0."
}
}
}

View file

@ -1,5 +1,5 @@
# This file managed by automation - do not edit manually
module InspecBin
INSPECBIN_ROOT = File.expand_path("..", __dir__)
VERSION = "4.26.15".freeze
VERSION = "4.41.17".freeze
end

View file

@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
.reject { |f| File.directory?(f) }
# Implementation dependencies
spec.add_dependency "chef-telemetry", "~> 1.0"
spec.add_dependency "chef-telemetry", "~> 1.0", ">= 1.0.8" # 1.0.8+ removes the http dep
spec.add_dependency "license-acceptance", ">= 0.2.13", "< 3.0"
spec.add_dependency "thor", ">= 0.20", "< 2.0"
spec.add_dependency "method_source", ">= 0.8", "< 2.0"
@ -35,7 +35,7 @@ Gem::Specification.new do |spec|
spec.add_dependency "mixlib-log", "~> 3.0"
spec.add_dependency "sslshake", "~> 1.2"
spec.add_dependency "parallel", "~> 1.9"
spec.add_dependency "faraday", ">= 0.9.0", "< 1.4"
spec.add_dependency "faraday", ">= 0.9.0", "< 1.5"
spec.add_dependency "faraday_middleware", "~> 1.0"
spec.add_dependency "tty-table", "~> 0.10"
spec.add_dependency "tty-prompt", "~> 0.17"

View file

@ -31,6 +31,7 @@ Gem::Specification.new do |spec|
# Train plugins we ship with InSpec
spec.add_dependency "train-habitat", "~> 0.1"
spec.add_dependency "train-aws", "~> 0.1"
spec.add_dependency "train-aws", "~> 0.2"
spec.add_dependency "train-winrm", "~> 0.2"
spec.add_dependency "mongo", "= 2.13.2" # 2.14 introduces a broken symlink in mongo-2.14.0/spec/support/ocsp
end

101
kitchen.dokken.yml Normal file
View file

@ -0,0 +1,101 @@
---
driver:
name: dokken
chef_version: :latest
privileged: true # because Docker and SystemD/Upstart
transport:
name: dokken
provisioner:
name: dokken
verifier:
name: inspec
sudo: true
# Test against every supported target platform for which we have a dokken image.
# If we don't have a dokken image, see kitchen.chef.yml for Vagrant-based testing.
# Try to keep this list up to date!
# Visit https://hub.docker.com/search and https://github.com/test-kitchen/dokken-images to search for new images
platforms:
- name: amazonlinux-2
driver:
image: dokken/amazonlinux-2
pid_one_command: /usr/lib/systemd/systemd
- name: centos-7
driver:
image: dokken/centos-7
pid_one_command: /usr/lib/systemd/systemd
- name: centos-8
driver:
image: dokken/centos-8
pid_one_command: /usr/lib/systemd/systemd
- name: debian-9
driver:
image: dokken/debian-9
pid_one_command: /bin/systemd
intermediate_instructions:
- RUN /usr/bin/apt-get update -y
- name: debian-10
driver:
image: dokken/debian-10
pid_one_command: /bin/systemd
intermediate_instructions:
- RUN /usr/bin/apt-get update -y
- name: fedora-latest
driver:
image: dokken/fedora-latest
pid_one_command: /usr/lib/systemd/systemd
- name: oraclelinux-7
driver:
image: dokken/oraclelinux-7
pid_one_command: /usr/lib/systemd/systemd
- name: oraclelinux-8
driver:
image: dokken/oraclelinux-8
pid_one_command: /usr/lib/systemd/systemd
- name: opensuse-leap
driver:
image: dokken/opensuse-leap-15
pid_one_command: /bin/systemd
- name: ubuntu-18.04
driver:
image: dokken/ubuntu-18.04
pid_one_command: /bin/systemd
intermediate_instructions:
- RUN /usr/bin/apt-get update -y
- name: ubuntu-20.04
driver:
image: dokken/ubuntu-20.04
pid_one_command: /bin/systemd
intermediate_instructions:
- RUN /usr/bin/apt-get update -y
suites:
- name: resources
run_list:
- recipe[os_prepare]
verifier:
inspec_tests:
# TODO - split these out into core, database, unix, and windows resources
- test/kitchen/policies/default
attributes:
osprepare:
docker: true
application: false
# These are planned for the future
# Suites which exercise resources that exercise databases
# - name: resources-database
# Unix-only resources
# - name: resources-unix
# Windows-only resources
# - name: resources-windows

View file

@ -1,122 +0,0 @@
---
driver:
name: dokken
chef_version: 14.12.9
privileged: true # because Docker and SystemD/Upstart
transport:
name: dokken
lifecycle:
pre_converge:
- local: cd inspec-bin && gem build inspec-core-bin.gemspec --output ../test/kitchen/cookbooks/install_inspec/files/inspec-core-bin.gem
- local: gem build inspec-core.gemspec --output test/kitchen/cookbooks/install_inspec/files/inspec-core.gem
provisioner:
name: dokken
client_rb:
data_collector.server_url: <%= ENV['COLLECTOR_URL'] %>
data_collector.token: <%= ENV['COLLECTOR_TOKEN'] %>
ssl_verify_mode: :verify_none
verify_api_cert: false
verifier:
name: inspec
sudo: true
platforms:
- name: amazonlinux
driver:
image: dokken/amazonlinux
pid_one_command: /sbin/init
- name: amazonlinux-2
driver:
image: dokken/amazonlinux-2
pid_one_command: /usr/lib/systemd/systemd
- name: centos-6
driver:
image: dokken/centos-6
pid_one_command: /sbin/init
- name: centos-7
driver:
image: dokken/centos-7
pid_one_command: /usr/lib/systemd/systemd
- name: debian-9
driver:
image: dokken/debian-9
pid_one_command: /bin/systemd
intermediate_instructions:
- RUN /usr/bin/apt-get update -y
- name: debian-10
driver:
image: dokken/debian-10
pid_one_command: /bin/systemd
intermediate_instructions:
- RUN /usr/bin/apt-get update -y
- name: fedora-29
driver:
image: dokken/fedora-29
pid_one_command: /usr/lib/systemd/systemd
- name: oraclelinux-6
driver:
image: dokken/oraclelinux-6
pid_one_command: /sbin/init
- name: oraclelinux-7
driver:
image: dokken/oraclelinux-7
pid_one_command: /usr/lib/systemd/systemd
- name: opensuse-leap
driver:
image: dokken/opensuse-leap-42
pid_one_command: /bin/systemd
- name: ubuntu-16.04
driver:
image: dokken/ubuntu-16.04
pid_one_command: /bin/systemd
intermediate_instructions:
- RUN /usr/bin/apt-get update -y
- name: ubuntu-18.04
driver:
image: dokken/ubuntu-18.04
pid_one_command: /bin/systemd
intermediate_instructions:
- RUN /usr/bin/apt-get update -y
suites:
- name: resources-core
run_list:
- recipe[os_prepare]
- recipe[audit]
verifier:
inspec_tests:
- test/kitchen/policies/resources-core
attributes:
audit:
attributes:
audit_attribute: 'Attribute Override!'
insecure: true
reporter: ['json-file','chef-automate']
fetcher: 'chef-automate'
json_file:
location: /tmp/json_export.json
profiles:
- name: integration
url: https://github.com/inspec/inspec-integration-profile/archive/master.zip
osprepare:
docker: true
application: false
- name: resources-database
- name: resources-unix
- name: resources-windows

View file

@ -43,11 +43,15 @@ module Inspec
begin
if (allowed_commands & ARGV.map(&:downcase)).empty? && # Did they use a non-exempt command?
!ARGV.empty? # Did they supply at least one command?
LicenseAcceptance::Acceptor.check_and_persist(
license_acceptor_output = LicenseAcceptance::Acceptor.check_and_persist(
Inspec::Dist::EXEC_NAME,
Inspec::VERSION,
logger: Inspec::Log
)
if license_acceptor_output && ARGV.count == 1 && (ARGV.first.include? "--chef-license")
Inspec::UI.new.exit
end
license_acceptor_output
end
rescue LicenseAcceptance::LicenseNotAcceptedError
Inspec::Log.error "#{Inspec::Dist::PRODUCT_NAME} cannot execute without accepting the license"
@ -120,6 +124,8 @@ module Inspec
desc: "Provide a ID which will be included on reports"
option :winrm_shell_type, type: :string, default: "powershell",
desc: "Specify a shell type for winrm (eg. 'elevated' or 'powershell')"
option :docker_url, type: :string,
desc: "Provides path to Docker API endpoint (Docker)"
end
def self.profile_options
@ -134,6 +140,8 @@ module Inspec
profile_options
option :controls, type: :array,
desc: "A list of control names to run, or a list of /regexes/ to match against control names. Ignore all other tests."
option :tags, type: :array,
desc: "A list of tags names that are part of controls to filter and run controls, or a list of /regexes/ to match against tags names of controls. Ignore all other tests."
option :reporter, type: :array,
banner: "one two:/output/file/path",
desc: "Enable one or more output reporters: cli, documentation, html, progress, json, json-min, json-rspec, junit, yaml"
@ -164,6 +172,13 @@ module Inspec
desc: "Use --no-diff to suppress 'diff' output of failed textual test results."
option :sort_results_by, type: :string, default: "file", banner: "--sort-results-by=none|control|file|random",
desc: "After normal execution order, results are sorted by control ID, or by file (default), or randomly. None uses legacy unsorted mode."
option :filter_empty_profiles, type: :boolean, default: false,
desc: "Filter empty profiles (profiles without controls) from the report."
option :command_timeout, type: :numeric,
desc: "Maximum seconds to allow commands to run during execution.",
long_desc: "Maximum seconds to allow commands to run during execution. A timed out command is considered an error."
option :reporter_include_source, type: :boolean, default: false,
desc: "Include full source code of controls in the CLI report"
end
def self.help(*args)
@ -172,7 +187,7 @@ module Inspec
puts " Patents: chef.io/patents\n\n"
end
def self.format_platform_info(params: {}, indent: 0, color: 39)
def self.format_platform_info(params: {}, indent: 0, color: 39, enable_color: true)
str = ""
params.each do |item, info|
data = info
@ -183,7 +198,7 @@ module Inspec
# Do not output fields of data is missing ('unknown' is fine)
next if data.nil?
data = "\e[1m\e[#{color}m#{data}\e[0m"
data = "\e[1m\e[#{color}m#{data}\e[0m" if enable_color
str << format("#{" " * indent}%-10s %s\n", item.to_s.capitalize + ":", data)
end
str

View file

@ -6,9 +6,9 @@ module Inspec
extend Forwardable
attr_reader :cache, :target, :fetcher
def initialize(target, cache)
def initialize(target, cache, opts = {})
@target = target
@fetcher = Inspec::Fetcher::Registry.resolve(target)
@fetcher = Inspec::Fetcher::Registry.resolve(target, opts)
if @fetcher.nil?
raise("Could not fetch inspec profile in #{target.inspect}.")

View file

@ -65,6 +65,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI
desc: "Save the created profile to a path"
option :controls, type: :array,
desc: "A list of controls to include. Ignore all other tests."
option :tags, type: :array,
desc: "A list of tags to filter controls and include only those. Ignore all other tests."
profile_options
def json(target)
require "json" unless defined?(JSON)
@ -218,9 +220,13 @@ class Inspec::InspecCLI < Inspec::BaseCLI
Automate:
```
#{Inspec::Dist::EXEC_NAME} compliance login
#{Inspec::Dist::EXEC_NAME} automate login
#{Inspec::Dist::EXEC_NAME} exec compliance://username/linux-baseline
```
`inspec compliance` is a backwards compatible alias for `inspec automate` and works the same way:
```
#{Inspec::Dist::EXEC_NAME} compliance login
```
Supermarket:
```
@ -301,7 +307,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
puts res.to_json
else
ui.headline("Platform Details")
ui.plain Inspec::BaseCLI.format_platform_info(params: res, indent: 0, color: 36)
ui.plain Inspec::BaseCLI.format_platform_info(params: res, indent: 0, color: 36, enable_color: ui.color?)
end
rescue ArgumentError, RuntimeError, Train::UserError => e
$stderr.puts e.message
@ -321,7 +327,14 @@ class Inspec::InspecCLI < Inspec::BaseCLI
desc: "A space-delimited list of local folders containing profiles whose libraries and resources will be loaded into the new shell"
option :distinct_exit, type: :boolean, default: true,
desc: "Exit with code 100 if any tests fail, and 101 if any are skipped but none failed (default). If disabled, exit 0 on skips and 1 for failures."
option :command_timeout, type: :numeric,
desc: "Maximum seconds to allow a command to run.",
long_desc: "Maximum seconds to allow commands to run. A timed out command is considered an error."
option :inspect, type: :boolean, default: false, desc: "Use verbose/debugging output for resources."
option :input_file, type: :array,
desc: "Load one or more input files, a YAML file with values for the shell to use"
option :input, type: :array, banner: "name1=value1 name2=value2",
desc: "Specify one or more inputs directly on the command line to the shell, as --input NAME=VALUE. Accepts single-quoted YAML and JSON structures."
def shell_func
o = config
diagnose(o)
@ -395,6 +408,20 @@ class Inspec::InspecCLI < Inspec::BaseCLI
end
map %w{-v --version} => :version
desc "clear_cache", "clears the InSpec cache. Useful for debugging."
option :vendor_cache, type: :string,
desc: "Use the given path for caching dependencies. (default: ~/.inspec/cache)"
def clear_cache
o = config
configure_logger(o)
cache_path = o[:vendor_cache] || "~/.inspec/cache"
FileUtils.rm_r Dir.glob(File.expand_path(cache_path))
o[:logger] = Logger.new($stdout)
o[:logger].level = get_log_level(o[:log_level])
o[:logger].info "== InSpec cache cleared successfully =="
end
private
def run_command(opts)

View file

@ -53,11 +53,23 @@ module Inspec
def control(id, opts = {}, &block)
opts[:skip_only_if_eval] = @skip_only_if_eval
register_control(Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block))
tag_ids = control_tags(&block)
if (controls_list_empty? && tags_list_empty?) || control_exist_in_controls_list?(id) || tag_exist_in_control_tags?(tag_ids)
register_control(Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block))
end
end
alias rule control
def control_tags(&block)
tag_source = block.source.split("\n").select { |src| src.split.first.eql?("tag") }
tag_source = tag_source.map { |src| src.sub("tag", "").strip }.map { |src| src.split(",").map { |final_src| final_src.sub(/([^:]*):/, "") } }.flatten
output = tag_source.map { |src| src.sub(/\[|\]/, "") }.map { |src| instance_eval(src) }
output.compact.uniq
rescue
[]
end
# Describe allows users to write rspec-like bare describe
# blocks without declaring an inclosing control. Here, we
# generate a control for them automatically and then execute
@ -68,10 +80,14 @@ module Inspec
id = "(generated from #{loc} #{SecureRandom.hex})"
res = nil
rule = Inspec::Rule.new(id, profile_id, resources_dsl, {}) do
res = describe(*args, &block)
end
register_control(rule, &block)
if controls_list_empty? || control_exist_in_controls_list?(id)
register_control(rule, &block)
end
res
end
@ -176,5 +192,55 @@ module Inspec
"#{File.basename(path)}:#{line}"
end
end
# Returns true if configuration hash is not empty and it contains the list of controls is not empty
def profile_config_exist?
!@conf.empty? && @conf.key?("profile") && !@conf["profile"].include_controls_list.empty?
end
def profile_tag_config_exist?
!@conf.empty? && @conf.key?("profile") && !@conf["profile"].include_tags_list.empty?
end
# Returns true if configuration hash is empty or configuration hash does not have the list of controls that needs to be included
def controls_list_empty?
!@conf.empty? && @conf.key?("profile") && @conf["profile"].include_controls_list.empty? || @conf.empty?
end
def tags_list_empty?
!@conf.empty? && @conf.key?("profile") && @conf["profile"].include_tags_list.empty? || @conf.empty?
end
# Check if the given control exist in the --controls option
def control_exist_in_controls_list?(id)
id_exist_in_list = false
if profile_config_exist?
id_exist_in_list = @conf["profile"].include_controls_list.any? do |inclusion|
# Try to see if the inclusion is a regex, and if it matches
inclusion == id || (inclusion.is_a?(Regexp) && inclusion =~ id)
end
end
id_exist_in_list
end
# Check if the given control exist in the --tags option
def tag_exist_in_control_tags?(tag_ids)
tag_option_matches_with_list = false
if !tag_ids.empty? && !tag_ids.nil? && profile_tag_config_exist?
tag_option_matches_with_list = !(tag_ids & @conf["profile"].include_tags_list).empty?
unless tag_option_matches_with_list
@conf["profile"].include_tags_list.any? do |inclusion|
# Try to see if the inclusion is a regex, and if it matches
if inclusion.is_a?(Regexp)
tag_ids.each do |id|
tag_option_matches_with_list = (inclusion =~ id)
break if tag_option_matches_with_list
end
end
end
end
end
tag_option_matches_with_list
end
end
end

View file

@ -2,12 +2,12 @@ require "inspec/plugin/v1"
module Inspec
class FetcherRegistry < PluginRegistry
def resolve(target)
def resolve(target, opts = {})
if fetcher_specified?(target)
super(target)
super(target, opts)
else
Inspec::Log.debug("Assuming default supermarket source for #{target}")
super(with_default_fetcher(target))
super(with_default_fetcher(target), opts)
end
end

View file

@ -62,7 +62,6 @@ module Inspec::Fetcher
def fetch(destination_path)
@repo_directory = destination_path # Might be the cache, or vendoring, or something else
FileUtils.mkdir_p(destination_path) unless Dir.exist?(destination_path)
if cloned?
checkout
else
@ -126,10 +125,25 @@ module Inspec::Fetcher
elsif @tag
resolve_ref(@tag)
else
resolve_ref("master")
resolve_ref(default_ref)
end
end
def default_ref
command_string = "git remote show #{@remote_url}"
cmd = shellout(command_string)
unless cmd.exitstatus == 0
raise(Inspec::FetcherFailure, "Profile git dependency failed with default reference - #{@remote_url} - error running '#{command_string}': #{cmd.stderr}")
else
ref = cmd.stdout.lines.detect { |l| l.include? "HEAD branch:" }&.split(":")&.last&.strip
unless ref
raise(Inspec::FetcherFailure, "Profile git dependency failed with default reference - #{@remote_url} - error running '#{command_string}': NULL reference")
end
ref
end
end
def resolve_ref(ref_name)
command_string = "git ls-remote \"#{@remote_url}\" \"#{ref_name}*\""
cmd = shellout(command_string)

View file

@ -3,7 +3,8 @@ require "openssl" unless defined?(OpenSSL)
module Inspec::Fetcher
class Local < Inspec.fetcher(1)
name "local"
priority 0
priority 1
# Priority is used for setting precedence of fetchers. And registry plugin(v1) decides which fetcher to use for loading profiles by using this priority
def self.resolve(target)
if target.is_a?(String)
@ -31,7 +32,7 @@ module Inspec::Fetcher
target = target.gsub(%r{^file://}, "")
else
# support for windows paths
target = target.tr('\\', "/")
target = target.tr("\\", "/")
end
target if File.exist?(File.expand_path(target))

View file

@ -6,9 +6,11 @@ module Inspec::Fetcher
priority 0
def self.resolve(target)
return nil unless target.is_a? Hash
new(target)
if (target.is_a? Hash) && ((target.keys & %i{cwd path backend}).empty?)
new(target)
else
nil
end
end
def initialize(data)

View file

@ -19,12 +19,17 @@ module Inspec
attr_accessor :input_name
attr_accessor :input_value
attr_accessor :input_type
attr_accessor :input_pattern
end
class TypeError < Error
attr_accessor :input_type
end
class PatternError < Error
attr_accessor :input_pattern
end
class RequiredError < Error
attr_accessor :input_name
end
@ -56,7 +61,6 @@ module Inspec
def initialize(properties = {})
@value_has_been_set = false
properties.each do |prop_name, prop_value|
if EVENT_PROPERTIES.include? prop_name
# OK, save the property
@ -174,7 +178,7 @@ module Inspec
# are free to go higher.
DEFAULT_PRIORITY_FOR_VALUE_SET = 60
attr_reader :description, :events, :identifier, :name, :required, :sensitive, :title, :type
attr_reader :description, :events, :identifier, :name, :required, :sensitive, :title, :type, :pattern
def initialize(name, options = {})
@name = name
@ -192,7 +196,6 @@ module Inspec
# debugging record of when and how the value changed.
@events = []
events.push make_creation_event(options)
update(options)
end
@ -213,6 +216,7 @@ module Inspec
def update(options)
_update_set_metadata(options)
normalize_type_restriction!
normalize_pattern_restriction!
# Values are set by passing events in; but we can also infer an event.
if options.key?(:value) || options.key?(:default)
@ -227,6 +231,7 @@ module Inspec
events << options[:event] if options.key? :event
enforce_type_restriction!
enforce_pattern_restriction!
end
# We can determine a value:
@ -268,6 +273,7 @@ module Inspec
@identifier = options[:identifier] if options.key?(:identifier) # TODO: determine if this is ever used
@type = options[:type] if options.key?(:type)
@sensitive = options[:sensitive] if options.key?(:sensitive)
@pattern = options[:pattern] if options.key?(:pattern)
end
def make_creation_event(options)
@ -310,7 +316,9 @@ module Inspec
file: location.path,
line: location.lineno
)
enforce_type_restriction!
enforce_pattern_restriction!
end
def value
@ -324,7 +332,7 @@ module Inspec
def to_hash
as_hash = { name: name, options: {} }
%i{description title identifier type required value sensitive}.each do |field|
%i{description title identifier type required value sensitive pattern}.each do |field|
val = send(field)
next if val.nil?
@ -407,6 +415,33 @@ module Inspec
@type = type_req
end
def enforce_pattern_restriction!
return unless pattern
return unless has_value?
string_value = current_value(false).to_s
valid_pattern = string_value.match?(pattern)
unless valid_pattern
error = Inspec::Input::ValidationError.new
error.input_name = @name
error.input_value = string_value
error.input_pattern = pattern
raise error, "Input '#{error.input_name}' with value '#{error.input_value}' does not validate to pattern '#{error.input_pattern}'."
end
end
def normalize_pattern_restriction!
return unless pattern
unless valid_regexp?(pattern)
error = Inspec::Input::PatternError.new
error.input_pattern = pattern
raise error, "Pattern '#{error.input_pattern}' is not a valid regex pattern."
end
@pattern = pattern
end
def valid_numeric?(value)
Float(value)
true

View file

@ -82,6 +82,7 @@ module Inspec
def find_or_register_input(input_name, profile_name, options = {})
input_name = input_name.to_s
profile_name = profile_name.to_s
options[:event].value = Thor::CoreExt::HashWithIndifferentAccess.new(options[:event].value) if options[:event]&.value.is_a?(Hash)
if profile_alias?(profile_name) && !profile_aliases[profile_name].nil?
alias_name = profile_name
@ -324,6 +325,7 @@ module Inspec
type: input_options[:type],
required: input_options[:required],
sensitive: input_options[:sensitive],
pattern: input_options[:pattern],
event: evt
)
end

View file

@ -20,7 +20,7 @@ module Inspec
def to_hash
as_hash = { name: name, options: {} }
%i{description title identifier type required value}.each do |field|
%i{description title identifier type required value pattern}.each do |field|
val = send(field)
next if val.nil?

View file

@ -9,9 +9,13 @@ class PluginRegistry
#
# @param [String] target to resolve
# @return [Plugin] plugin instance if it can be resolved, nil otherwise
def resolve(target)
def resolve(target, opts = {})
modules.each do |m|
res = m.resolve(target)
res = if Inspec::Fetcher::Url == m
m.resolve(target, opts)
else
m.resolve(target)
end
return res unless res.nil?
end
nil

View file

@ -117,6 +117,15 @@ module Inspec::Plugin::V2
# `inspec dosomething` => activate the :dosomething hook
activate_me ||= cli_args.include?(act.activator_name.to_s)
# Only one compliance command to be activated at one time.
# Since both commands are defined in the same class,
# activators were not getting fetched uniquely.
if cli_args.include?("automate") && act.activator_name.to_s.eql?("compliance")
activate_me = false
elsif cli_args.include?("compliance") && act.activator_name.to_s.eql?("automate")
activate_me = false
end
# OK, activate.
if activate_me
act.activate

View file

@ -18,9 +18,9 @@ module Inspec
class Profile
extend Forwardable
def self.resolve_target(target, cache)
def self.resolve_target(target, cache, opts = {})
Inspec::Log.debug "Resolve #{target} into cache #{cache.path}"
Inspec::CachedFetcher.new(target, cache)
Inspec::CachedFetcher.new(target, cache, opts)
end
# Check if the profile contains a vendored cache, move content into global cache
@ -70,7 +70,11 @@ module Inspec
def self.for_target(target, opts = {})
opts[:vendor_cache] ||= Cache.new
fetcher = resolve_target(target, opts[:vendor_cache])
config = {}
unless opts[:runner_conf].nil?
config = opts[:runner_conf].respond_to?(:final_options) ? opts[:runner_conf].final_options : opts[:runner_conf]
end
fetcher = resolve_target(target, opts[:vendor_cache], config)
for_fetcher(fetcher, opts)
end
@ -87,6 +91,7 @@ module Inspec
@logger = options[:logger] || Logger.new(nil)
@locked_dependencies = options[:dependencies]
@controls = options[:controls] || []
@tags = options[:tags] || []
@writable = options[:writable] || false
@profile_id = options[:id]
@profile_name = options[:profile_name]
@ -206,7 +211,7 @@ module Inspec
@params ||= load_params
end
def collect_tests(include_list = @controls)
def collect_tests
unless @tests_collected || failed?
return unless supports_platform?
@ -225,14 +230,17 @@ module Inspec
end
@tests_collected = true
end
filter_controls(@runner_context.all_rules, include_list)
@runner_context.all_rules
end
def filter_controls(controls_array, include_list)
return controls_array if include_list.nil? || include_list.empty?
# This creates the list of controls provided in the --controls options which need to be include
# for evaluation.
def include_controls_list
return [] if @controls.nil? || @controls.empty?
included_controls = @controls
# Check for anything that might be a regex in the list, and make it official
include_list.each_with_index do |inclusion, index|
included_controls.each_with_index do |inclusion, index|
next if inclusion.is_a?(Regexp)
# Insist the user wrap the regex in slashes to demarcate it as a regex
next unless inclusion.start_with?("/") && inclusion.end_with?("/")
@ -240,21 +248,38 @@ module Inspec
inclusion = inclusion[1..-2] # Trim slashes
begin
re = Regexp.new(inclusion)
include_list[index] = re
included_controls[index] = re
rescue RegexpError => e
warn "Ignoring unparseable regex '/#{inclusion}/' in --control CLI option: #{e.message}"
include_list[index] = nil
included_controls[index] = nil
end
end
include_list.compact!
included_controls.compact!
included_controls
end
controls_array.select do |c|
id = ::Inspec::Rule.rule_id(c)
include_list.any? do |inclusion|
# Try to see if the inclusion is a regex, and if it matches
inclusion == id || (inclusion.is_a?(Regexp) && inclusion =~ id)
# This creates the list of controls to be filtered by tag values provided in the --tags options
def include_tags_list
return [] if @tags.nil? || @tags.empty?
included_tags = @tags
# Check for anything that might be a regex in the list, and make it official
included_tags.each_with_index do |inclusion, index|
next if inclusion.is_a?(Regexp)
# Insist the user wrap the regex in slashes to demarcate it as a regex
next unless inclusion.start_with?("/") && inclusion.end_with?("/")
inclusion = inclusion[1..-2] # Trim slashes
begin
re = Regexp.new(inclusion)
included_tags[index] = re
rescue RegexpError => e
warn "Ignoring unparseable regex '/#{inclusion}/' in --control CLI option: #{e.message}"
included_tags[index] = nil
end
end
included_tags.compact!
included_tags
end
def load_libraries

View file

@ -91,7 +91,7 @@ module Inspec
end
def all_controls
ret = @rules.values
ret = @rules.values.compact
ret += @control_subcontexts.map(&:all_rules).flatten
ret
end

View file

@ -41,12 +41,14 @@ module Inspec::Reporters
MULTI_TEST_CONTROL_SUMMARY_MAX_LEN = 60
def render
@src_extent_map = {}
run_data[:profiles].each do |profile|
if profile[:status] == "skipped"
platform = run_data[:platform]
output("Skipping profile: '#{profile[:name]}' on unsupported platform: '#{platform[:name]}/#{platform[:release]}'.")
next
end
read_control_source(profile)
@control_count = 0
output("")
print_profile_header(profile)
@ -89,6 +91,7 @@ module Inspec::Reporters
next if control.results.nil?
output(format_control_header(control))
output(format_control_source(control)) if Inspec::Config.cached[:reporter_include_source]
control.results.each do |result|
output(format_result(control, result, :standard))
@control_count += 1
@ -127,6 +130,62 @@ module Inspec::Reporters
)
end
def format_control_source(control)
src = @control_source[control.id]
message = "Control Source from #{src[:path]}:#{src[:start]}..#{src[:end]}\n"
message += src[:content]
format_message(
color: "skipped",
indentation: 5,
message: message
)
end
def read_control_source(profile)
return unless Inspec::Config.cached[:reporter_include_source]
@control_source = {}
src_extent_map = {}
# First pass: build map of paths => ids => [start]
all_unique_controls.each do |control|
id = control[:id]
path = control[:source_location][:ref]
start = control[:source_location][:line]
next if path.nil? || start.nil?
src_extent_map[path] ||= []
src_extent_map[path] << { start: start, id: id }
end
# Now sort the controls by their starting line in their control file
src_extent_map.values.each do |extent_list|
extent_list.sort! { |a, b| a[:start] <=> b[:start] }
end
# Third pass: Read in files and split into lines
src_extent_map.keys.each do |path|
control_file_lines = File.read(path).lines # TODO error handling
last_line_in_file = control_file_lines.count
extent_list = src_extent_map[path]
extent_list.each_with_index do |extent, idx|
if idx == extent_list.count - 1 # Last entry
extent[:end] = last_line_in_file
else
extent[:end] = extent_list[idx + 1][:start] - 1
end
@control_source[extent[:id]] =
{
path: path,
start: extent[:start],
end: extent[:end],
content: control_file_lines.slice(extent[:start] - 1, extent[:end] - extent[:start] + 1).join(""),
}
end
end
end
def format_result(control, result, type)
impact = control.impact_string_for_result(result)
@ -170,7 +229,7 @@ module Inspec::Reporters
end
def all_unique_controls
@unique_controls ||= begin
@unique_controls ||= begin # rubocop:disable Style/RedundantBegin
run_data[:profiles].flat_map do |profile|
profile[:controls]
end.uniq
@ -312,6 +371,10 @@ module Inspec::Reporters
data[:impact]
end
def source_location
data[:source_location]
end
def anonymous?
id.start_with?("(generated from ")
end

View file

@ -8,7 +8,7 @@ module Inspec::Reporters
end
def report
{
output = {
platform: platform,
profiles: profiles,
statistics: {
@ -16,6 +16,11 @@ module Inspec::Reporters
},
version: run_data[:version],
}
%w{passthrough}.each do |option|
output[option.to_sym] = @config[option] unless @config[option].nil?
end
output
end
private

View file

@ -24,7 +24,7 @@ module Inspec::Reporters
version: run_data[:version],
}
# optional json-config passthrough options
# optional jsonconfig passthrough options
%w{node_name environment roles job_uuid passthrough}.each do |option|
output[option.to_sym] = @config[option] unless @config[option].nil?
end

View file

@ -71,6 +71,9 @@ require "inspec/resources/key_rsa"
require "inspec/resources/ksh"
require "inspec/resources/limits_conf"
require "inspec/resources/login_defs"
require "inspec/resources/mongodb"
require "inspec/resources/mongodb_conf"
require "inspec/resources/mongodb_session"
require "inspec/resources/mount"
require "inspec/resources/mssql_session"
require "inspec/resources/mysql"
@ -81,6 +84,8 @@ require "inspec/resources/nginx_conf"
require "inspec/resources/npm"
require "inspec/resources/ntp_conf"
require "inspec/resources/oneget"
require "inspec/resources/opa_cli"
require "inspec/resources/opa_api"
require "inspec/resources/oracledb_session"
require "inspec/resources/os"
require "inspec/resources/os_env"
@ -103,6 +108,7 @@ require "inspec/resources/rabbitmq_config"
require "inspec/resources/registry_key"
require "inspec/resources/security_identifier"
require "inspec/resources/security_policy"
require "inspec/resources/selinux"
require "inspec/resources/service"
require "inspec/resources/shadow"
require "inspec/resources/ssh_config"

View file

@ -82,7 +82,7 @@ module Inspec::Resources
end
end
@params.merge!(params)
@params.merge!(params) { |key, current_val, new_val| [*current_val].to_a + [*new_val].to_a }
to_read = to_read.drop(1)
to_read += include_files(params).find_all do |fp|
@ -101,12 +101,14 @@ module Inspec::Resources
include_files_optional = params["IncludeOptional"] || []
includes = []
(include_files + include_files_optional).each do |f|
id = Pathname.new(f).absolute? ? f : File.join(conf_dir, f)
files = find_files(id, depth: 1, type: "file")
files += find_files(id, depth: 1, type: "link")
unless conf_dir.nil?
(include_files + include_files_optional).each do |f|
id = Pathname.new(f).absolute? ? f : File.join(conf_dir, f)
files = find_files(id, depth: 1, type: "file")
files += find_files(id, depth: 1, type: "link")
includes.push(files) if files
includes.push(files) if files
end
end
# [].flatten! == nil

View file

@ -78,7 +78,7 @@ module Inspec::Resources
return @repo_cache if defined?(@repo_cache)
# load all lists
cmd = inspec.command("find /etc/apt/ -name \*.list -exec sh -c 'cat {} || echo -n' \\;")
cmd = inspec.command("find /etc/apt/ -name \"*.list\" -exec sh -c 'cat {} || echo -n' \\;")
# @see https://help.ubuntu.com/community/Repositories/CommandLine#Explanation_of_the_Repository_Format
@repo_cache = cmd.stdout.lines.map do |raw_line|

View file

@ -16,6 +16,8 @@ module Inspec::Resources
include FileReader
attr_reader :conf_path, :content, :params
def initialize(path = nil)
@conf_path = path || "/etc/audit/auditd.conf"
@content = read_file_content(@conf_path)

View file

@ -31,6 +31,11 @@ module Inspec::Resources
end
@command = cmd
cli_timeout = Inspec::Config.cached["command_timeout"]&.to_i
# Can access this via Inspec::InspecCLI.commands["exec"].options[:command_timeout].default,
# but that may not be loaded for kitchen-inspec and other pure gem consumers
cli_timeout = nil if cli_timeout == 0 # Under test-kitchen we get a 0 timeout, which can't be a resonable value
@timeout = cli_timeout || options[:timeout]&.to_i
if options[:redact_regex]
unless options[:redact_regex].is_a?(Regexp)
@ -44,7 +49,15 @@ module Inspec::Resources
end
def result
@result ||= inspec.backend.run_command(@command)
@result ||= begin
inspec.backend.run_command(@command, timeout: @timeout)
rescue Train::CommandTimeoutReached
# Without a small sleep, the train connection gets broken
# We've already timed out, so a small sleep is not likely to be painful here.
sleep 0.1
raise Inspec::Exceptions::ResourceFailed,
"Command `#{@command}` timed out after #{@timeout} seconds"
end
end
def stdout

View file

@ -136,10 +136,10 @@ module Inspec::Resources
alias sticky? sticky
def more_permissive_than?(max_mode = nil)
raise Inspec::Exceptions::ResourceFailed, "The file" + file.path + "doesn't seem to exist" unless exist?
raise ArgumentError, "You must proivde a value for the `maximum allowable permission` for the file." if max_mode.nil?
raise ArgumentError, "You must proivde the `maximum permission target` as a `String`, you provided: " + max_mode.class.to_s unless max_mode.is_a?(String)
raise ArgumentError, "The value of the `maximum permission target` should be a valid file mode in 4-ditgit octal format: for example, `0644` or `0777`" unless /(0)?([0-7])([0-7])([0-7])/.match?(max_mode)
return nil unless exist?
raise ArgumentError, "You must provide a value for the `maximum allowable permission` for the file." if max_mode.nil?
raise ArgumentError, "You must provide the `maximum permission target` as a `String`, you provided: " + max_mode.class.to_s unless max_mode.is_a?(String)
raise ArgumentError, "The value of the `maximum permission target` should be a valid file mode in 4-digit octal format: for example, `0644` or `0777`" unless /(0)?([0-7])([0-7])([0-7])/.match?(max_mode)
# Using the files mode and a few bit-wise calculations we can ensure a
# file is no more permisive than desired.
@ -160,7 +160,6 @@ module Inspec::Resources
max_mode = max_mode.to_i(8)
inv_mode = 0777 ^ max_mode
inv_mode & file.mode != 0
end

View file

@ -49,10 +49,11 @@ module Inspec::Resources
filter = FilterTable.create
filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
filter.register_column(:names, field: "name")
.register_column(:gids, field: "gid")
.register_column(:domains, field: "domain")
.register_column(:members, field: "members", style: :simple)
filter.register_column(:names, field: "name")
.register_column(:gids, field: "gid")
.register_column(:domains, field: "domain")
.register_column(:members, field: "members", style: :simple)
.register_column(:members_array, field: "members_array", style: :simple)
filter.install_filter_methods_on_resource(self, :collect_group_details)
def to_s
@ -63,7 +64,13 @@ module Inspec::Resources
# collects information about every group
def collect_group_details
return @groups_cache ||= @group_provider.groups unless @group_provider.nil?
unless @group_provider.nil?
modified_groups_info = @group_provider.groups
unless modified_groups_info.empty?
modified_groups_info.each { |hashmap| hashmap["members_array"] = hashmap["members"].is_a?(Array) ? hashmap["members"] : hashmap["members"]&.split(",") }
end
return @groups_cache ||= modified_groups_info
end
[]
end
@ -111,7 +118,11 @@ module Inspec::Resources
end
def members
flatten_entry(group_info, "members")
flatten_entry(group_info, "members") || empty_value_for_members
end
def members_array
flatten_entry(group_info, "members_array") || []
end
def local
@ -141,6 +152,10 @@ module Inspec::Resources
group = @group.dup
@groups_cache ||= inspec.groups.where { name == group }
end
def empty_value_for_members
inspec.os.windows? ? [] : ""
end
end
class GroupInfo

View file

@ -57,7 +57,7 @@ module Inspec::Resources
end
def body
@worker.body
@worker.body&.force_encoding(Encoding::UTF_8)
end
def http_method

View file

@ -0,0 +1,65 @@
module Inspec::Resources
class Mongodb < Inspec.resource(1)
name "mongodb"
supports platform: "unix"
supports platform: "windows"
desc "The 'mongodb' resource is a helper for the 'mongodb_conf' & 'mongodb_session' resources. Please use those instead."
attr_reader :conf_path
def initialize
case inspec.os[:family]
when "debian", "fedora", "redhat", "linux", "suse"
init_linux
when "darwin"
init_macos
when "windows"
init_windows
end
end
def to_s
"MongoDB"
end
private
def init_linux
@conf_path = "/etc/mongod.conf"
end
def init_macos
@conf_path = "/usr/local/etc/mongod.conf"
end
def init_windows
dir = "C:\\Program Files\\MongoDB\\Server"
@version = version_from_dir(dir)
unless @version.to_s.empty?
@conf_path = "#{dir}\\#{@version}\\bin\\mongod.cfg"
end
end
def version_from_dir(dir)
dirs = inspec.command("Get-ChildItem -Path \"#{dir}\" -Name").stdout
entries = dirs.lines.count
case entries
when 0
warn "Could not determine version of installed MongoDB by inspecting #{dir}"
nil
when 1
dir_to_version(dirs)
else
warn "Multiple versions of MongoDB installed or incorrect base dir #{dir}"
first = dir_to_version(dirs.lines.first)
warn "Using the first version found: #{first}"
first
end
end
def dir_to_version(dir)
dir.chomp.split("/").last
end
end
end

View file

@ -0,0 +1,39 @@
require "inspec/resources/json"
require "inspec/resources/mongodb"
module Inspec::Resources
class MongodbConf < JsonConfig
name "mongodb_conf"
supports platform: "unix"
supports platform: "windows"
desc "Use the mongodb_conf InSpec audit resource to test the contents of the configuration file for MongoDB, typically located at `/etc/mongod.conf` or `C:\\Program Files\\MongoDB\\Server\\<version>\\bin\\mongod.cfg`, depending on the platform."
example <<~EXAMPLE
describe mongodb_conf do
its(["storage", "dbPath"]) { should eq "/var/lib/mongodb" }
its(["net", "port"]) { should eq 27017 }
end
EXAMPLE
def initialize(conf_path = nil)
@conf_path = conf_path || inspec.mongodb.conf_path
if @conf_path.nil?
return skip_resource "MongoDB conf path is not set."
end
super(@conf_path)
end
private
def parse(content)
YAML.load(content)
rescue => e
raise Inspec::Exceptions::ResourceFailed, "Unable to parse `mongod.conf` or `mongod.cfg` file: #{e.message}"
end
def resource_base_name
"MongoDB Configuration"
end
end
end

View file

@ -0,0 +1,88 @@
require "mongo"
module Inspec::Resources
class Lines
attr_reader :params
def initialize(raw, desc)
@params = raw
@desc = desc
end
def to_s
@desc
end
end
class MongodbSession < Inspec.resource(1)
name "mongodb_session"
supports platform: "unix"
supports platform: "windows"
desc "Use the mongodb_session InSpec audit resource to run MongoDB command against a MongoDB Database."
example <<~EXAMPLE
# default values:
# host: "127.0.0.1"
# port: "27017"
# auth_source - default to database name
# auth_mech - :scram
describe mongodb_session(user: "foo", password: "bar", database: "test").query(usersInfo: "ian").params["users"].first["roles"].first do
its(["role"]) { should eq "readWrite" }
end
EXAMPLE
attr_reader :user, :host, :port, :database, :params
def initialize(opts = {})
@user = opts[:user] || nil
@password = opts[:password] || nil
@host = opts[:host] || "127.0.0.1"
@port = opts[:port] || "27017"
@database = opts[:database] || nil
@auth_mech = opts[:auth_mech] || :scram
@auth_source = opts[:auth_source] || @database
@ssl = opts[:ssl] || false
@ssl_cert = opts[:ssl_cert] || nil
@ssl_key = opts[:ssl_key] || nil
@ssl_ca_cert = opts[:ssl_ca_cert] || nil
@auth_mech_properties = opts[:auth_mech_properties] || {}
@client = nil
fail_resource "Can't run MongoDB checks without authentication." unless user && @password
fail_resource "You must provide a database name for the session." unless database
create_session
end
def query(command)
raise Inspec::Exceptions::ResourceFailed, "#{resource_exception_message}" if resource_failed?
Lines.new(@client.command(command).documents.first, "MongoDB query: #{command}")
rescue => e
raise Inspec::Exceptions::ResourceFailed, "Can't run MongoDB command Error: #{e.message}"
end
private
def create_session
raise Inspec::Exceptions::ResourceFailed, "#{resource_exception_message}" if resource_failed?
options = { user: "#{user}",
password: "#{@password}",
database: "#{database}",
auth_source: "#{@auth_source}",
auth_mech: @auth_mech,
}
options[:auth_mech_properties] = @auth_mech_properties unless @auth_mech_properties.empty?
options[:ssl] = @ssl
opitons[:ssl_key] = @ssl_key unless @ssl_key.nil?
options[:ssl_cert] = @ssl_cert unless @ssl_cert.nil?
options[:ssl_ca_cert] = @ssl_ca_cert unless @ssl_ca_cert.nil?
@client = Mongo::Client.new([ "#{host}:#{port}" ], options)
rescue => e
raise Inspec::Exceptions::ResourceFailed, "Can't run MongoDB command. Error: #{e.message}"
end
end
end

View file

@ -42,11 +42,7 @@ module Inspec::Resources
@local_mode = opts[:local_mode]
unless local_mode?
@host = opts[:host] || "localhost"
if opts.key?(:port)
@port = opts[:port]
else
@port = "1433"
end
@port = opts[:port]
end
@instance = opts[:instance]
@db_name = opts[:db_name]
@ -58,7 +54,7 @@ module Inspec::Resources
end
def query(q) # rubocop:disable Metrics/PerceivedComplexity
escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '""').gsub(/\$/, '\\$')
escaped_query = q.gsub(/\\/, "\\\\").gsub(/"/, '""').gsub(/\$/, '\\$')
# surpress 'x rows affected' in SQLCMD with 'set nocount on;'
cmd_string = "sqlcmd -Q \"set nocount on; #{escaped_query}\" -W -w 1024 -s ','"
cmd_string += " -U '#{@user}' -P '#{@password}'" unless @user.nil? || @password.nil?

View file

@ -44,10 +44,14 @@ module Inspec::Resources
@port = port
@socket = socket
init_fallback if user.nil? || pass.nil?
skip_resource("Can't run MySQL SQL checks without authentication") if @user.nil? || @pass.nil?
raise Inspec::Exceptions::ResourceFailed, "Can't run MySQL SQL checks without authentication." if @user.nil? || @pass.nil?
test_connection
end
def query(q, db = "")
raise Inspec::Exceptions::ResourceFailed, "#{resource_exception_message}" if resource_failed?
mysql_cmd = create_mysql_cmd(q, db)
cmd = if !@pass.nil?
inspec.command(mysql_cmd, redact_regex: /(mysql -u\w+ -p).+(\s-(h|S).*)/)
@ -56,7 +60,7 @@ module Inspec::Resources
end
out = cmd.stdout + "\n" + cmd.stderr
if cmd.exit_status != 0 || out =~ /Can't connect to .* MySQL server/ || out.downcase =~ /^error:.*/
Lines.new(out, "MySQL query with errors: #{q}", cmd.exit_status)
raise Inspec::Exceptions::ResourceFailed, "MySQL query with errors: #{out}"
else
Lines.new(cmd.stdout.strip, "MySQL query: #{q}", cmd.exit_status)
end
@ -68,6 +72,12 @@ module Inspec::Resources
private
# Querying on the database to make sure conneciton can be established. If not this will set the resource exception
# message which we raise before querying on the database using mysql_session object.
def test_connection
query("select now()")
end
def escape_string(query)
Shellwords.escape(query)
end
@ -75,7 +85,7 @@ module Inspec::Resources
def create_mysql_cmd(q, db = "")
# TODO: simple escape, must be handled by a library
# that does this securely
escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '\\"').gsub(/\$/, '\\$')
escaped_query = q.gsub(/\\/, "\\\\").gsub(/"/, '\\"').gsub(/\$/, '\\$')
# construct the query
command = "mysql"

View file

@ -0,0 +1,23 @@
require "inspec/resources/json"
module Inspec::Resources
class Opa < JsonConfig
name "opa"
supports platform: "unix"
supports platform: "windows"
attr_reader :result
def initialize(content)
@content = content
super({ content: @content })
end
private
def parse(content)
@content = YAML.load(content)
rescue => e
raise Inspec::Exceptions::ResourceFailed, "Unable to parse OPA query output: #{e.message}"
end
end
end

View file

@ -0,0 +1,39 @@
require "inspec/resources/opa"
module Inspec::Resources
class OpaApi < Opa
name "opa_api"
supports platform: "unix"
supports platform: "windows"
def initialize(opts = {})
@url = opts[:url] || nil
@data = opts[:data] || nil
fail_resource "OPA url and data are mandatory." if @url.nil? || @url.empty? || @data.nil? || @data.empty?
@content = load_result
super(@content)
end
def allow
@content["result"]
end
def to_s
"OPA api"
end
private
def load_result
raise Inspec::Exceptions::ResourceFailed, "#{resource_exception_message}" if resource_failed?
result = inspec.command("curl -X POST #{@url} -d @#{@data} -H 'Content-Type: application/json'")
if result.exit_status == 0
result.stdout.gsub("\n", "")
else
error = result.stdout + "\n" + result.stderr
raise Inspec::Exceptions::ResourceFailed, "Error while executing OPA query: #{error}"
end
end
end
end

View file

@ -0,0 +1,43 @@
require "inspec/resources/opa"
module Inspec::Resources
class OpaCli < Opa
name "opa_cli"
supports platform: "unix"
supports platform: "windows"
def initialize(opts = {})
@opa_executable_path = opts[:opa_executable_path] || "opa" # if this path is not provided then we will assume that it's been set in the ENV PATH
@policy = opts[:policy] || nil
@data = opts[:data] || nil
@query = opts[:query] || nil
if (@policy.nil? || @policy.empty?) || (@data.nil? || @data.empty?) || (@query.nil? || @query.empty?)
fail_resource "OPA policy, data and query are mandatory."
end
@content = load_result
super(@content)
end
def allow
@content["result"][0]["expressions"][0]["value"] if @content["result"][0]["expressions"][0]["text"].include?("allow")
end
def to_s
"OPA cli"
end
private
def load_result
raise Inspec::Exceptions::ResourceFailed, "#{resource_exception_message}" if resource_failed?
result = inspec.command("#{@opa_executable_path} eval -i '#{@data}' -d '#{@policy}' '#{@query}'")
if result.exit_status == 0
result.stdout.gsub("\n", "")
else
error = result.stdout + "\n" + result.stderr
raise Inspec::Exceptions::ResourceFailed, "Error while executing OPA query: #{error}"
end
end
end
end

View file

@ -38,11 +38,12 @@ module Inspec::Resources
@sqlcl_bin = opts[:sqlcl_bin] || nil
@sqlplus_bin = opts[:sqlplus_bin] || "sqlplus"
skip_resource "Option 'as_os_user' not available in Windows" if inspec.os.windows? && su_user
fail_resource "Can't run Oracle checks without authentication" unless su_user && (user || password)
fail_resource "You must provide a service name for the session" unless service
fail_resource "Can't run Oracle checks without authentication" unless su_user || (user || password)
end
def query(sql)
raise Inspec::Exceptions::ResourceFailed, "#{resource_exception_message}" if resource_failed?
if @sqlcl_bin && inspec.command(@sqlcl_bin).exist?
@bin = @sqlcl_bin
format_options = "set sqlformat csv\nSET FEEDBACK OFF"
@ -53,8 +54,17 @@ module Inspec::Resources
command = command_builder(format_options, sql)
inspec_cmd = inspec.command(command)
out = inspec_cmd.stdout + "\n" + inspec_cmd.stderr
DatabaseHelper::SQLQueryResult.new(inspec_cmd, parse_csv_result(inspec_cmd.stdout))
if inspec_cmd.exit_status != 0 || !inspec_cmd.stderr.empty? || out.downcase =~ /^error.*/
raise Inspec::Exceptions::ResourceFailed, "Oracle query with errors: #{out}"
else
begin
DatabaseHelper::SQLQueryResult.new(inspec_cmd, parse_csv_result(inspec_cmd.stdout))
rescue
raise Inspec::Exceptions::ResourceFailed, "Oracle query with errors: #{out}"
end
end
end
def to_s
@ -77,11 +87,11 @@ module Inspec::Resources
end
if @db_role.nil?
%{#{sql_prefix}#{bin} "#{user}"/"#{password}"@#{host}:#{port}/#{@service}#{sql_postfix}}
"#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service}#{sql_postfix}"
elsif @su_user.nil?
%{#{sql_prefix}#{bin} "#{user}"/"#{password}"@#{host}:#{port}/#{@service} as #{@db_role}#{sql_postfix}}
"#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service} as #{@db_role}#{sql_postfix}"
else
%{su - #{@su_user} -c "env ORACLE_SID=#{@service} #{@bin} / as #{@db_role}#{sql_postfix}"}
"su - #{@su_user} -c env ORACLE_SID=#{@service} #{@bin} / as #{@db_role}#{sql_postfix}"
end
end

View file

@ -117,7 +117,7 @@ module Inspec::Resources
if defined?(windows_paths["Python"]) && pipcmd.nil?
return nil if windows_paths["Pip"].nil?
pipdir = windows_paths["Python"].split('\\')
pipdir = windows_paths["Python"].split("\\")
# remove python.exe
pipdir.pop
pipcmd = pipdir.push("Scripts").push("pip.exe").join("/")

View file

@ -54,7 +54,7 @@ module Inspec::Resources
def port_manager_for_os
os = inspec.os
if os.linux?
LinuxPorts.new(inspec)
LinuxPorts.new(inspec, @port)
elsif os.aix?
# AIX: see http://www.ibm.com/developerworks/aix/library/au-lsof.html#resources
# and https://www-01.ibm.com/marketing/iwm/iwm/web/reg/pick.do?source=aixbp
@ -102,8 +102,9 @@ module Inspec::Resources
# }]
class PortsInfo
attr_reader :inspec
def initialize(inspec)
def initialize(inspec, port = nil)
@inspec = inspec
@port = port
end
end
@ -394,7 +395,12 @@ module Inspec::Resources
def ports_via_ss
return nil unless inspec.command("ss").exist?
cmd = inspec.command("ss -tulpen")
if @port.nil?
cmd = inspec.command("ss -tulpen")
else
cmd = inspec.command("ss -tulpen '( dport = #{@port} or sport = #{@port} )'")
end
return nil unless cmd.exit_status.to_i == 0
ports = []

Some files were not shown because too many files have changed in this diff Show more