mirror of
https://github.com/inspec/inspec
synced 2025-02-17 06:28:40 +00:00
Merge remote-tracking branch 'upstream/master' into add-startuser-systemd-service
Signed-off-by: Mendy Baitelman <mendy@baitelman.com>
This commit is contained in:
commit
1a9a47ee96
360 changed files with 4272 additions and 2755 deletions
|
@ -1,5 +1,6 @@
|
|||
[inspec]
|
||||
build_targets = [
|
||||
"x86_64-windows",
|
||||
"x86_64-linux",
|
||||
"x86_64-linux-kernel2"
|
||||
]
|
||||
]
|
||||
|
|
|
@ -26,3 +26,6 @@ plugins:
|
|||
enabled: true
|
||||
exclude_patterns:
|
||||
- "www/source/javascripts/"
|
||||
- "examples/"
|
||||
- "test/unit/mock/profiles/"
|
||||
- "test/kitchen"
|
18
.expeditor/artifact.habitat.yml
Normal file
18
.expeditor/artifact.habitat.yml
Normal file
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
steps:
|
||||
|
||||
- label: ":linux: Validate Habitat Builds of Chef InSpec"
|
||||
commands:
|
||||
- .expeditor/buildkite/artifact.habitat.test.sh
|
||||
expeditor:
|
||||
executor:
|
||||
linux:
|
||||
privileged: true
|
||||
|
||||
- label: ":windows: Validate Habitat Builds of Chef InSpec"
|
||||
commands:
|
||||
- .expeditor/buildkite/artifact.habitat.test.ps1
|
||||
expeditor:
|
||||
executor:
|
||||
windows:
|
||||
privileged: true
|
6
.expeditor/buildkite/artifact.habitat.install.sh
Executable file
6
.expeditor/buildkite/artifact.habitat.install.sh
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -ueo pipefail
|
||||
|
||||
hab origin key import < "$HAB_CI_KEY"
|
||||
hab pkg install --binlink "./results/${pkg_artifact:?is undefined}"
|
38
.expeditor/buildkite/artifact.habitat.test.ps1
Normal file
38
.expeditor/buildkite/artifact.habitat.test.ps1
Normal file
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env powershell
|
||||
|
||||
#Requires -Version 5
|
||||
|
||||
$env:HAB_ORIGIN = 'ci'
|
||||
$env:CHEF_LICENSE = 'accept-no-persist'
|
||||
$env:HAB_LICENSE = 'accept-no-persist'
|
||||
$Plan = 'inspec'
|
||||
|
||||
Write-Host "--- system details"
|
||||
$Properties = 'Caption', 'CSName', 'Version', 'BuildType', 'OSArchitecture'
|
||||
Get-CimInstance Win32_OperatingSystem | Select-Object $Properties | Format-Table -AutoSize
|
||||
|
||||
Write-Host "--- Installing the version of Habitat required"
|
||||
Install-Habitat --version 0.85.0.20190916
|
||||
|
||||
Write-Host "--- Generating fake origin key"
|
||||
hab origin key generate $env:HAB_ORIGIN
|
||||
|
||||
Write-Host "--- Building $Plan"
|
||||
$project_root = "$(git rev-parse --show-toplevel)"
|
||||
Set-Location $project_root
|
||||
|
||||
$env:DO_CHECK=$true; hab pkg build . -D
|
||||
if (-not $?) { throw "unable to build" }
|
||||
|
||||
. $project_root/results/last_build.ps1
|
||||
if (-not $?) { throw "unable to determine details about this build" }
|
||||
|
||||
Write-Host "--- Installing $pkg_ident/$pkg_artifact"
|
||||
hab pkg install $project_root/results/$pkg_artifact
|
||||
if (-not $?) { throw "unable to install this build" }
|
||||
|
||||
Write-Host "+++ Testing $Plan"
|
||||
Push-Location $project_root/test/artifact
|
||||
rake
|
||||
if (-not $?) { throw "rake failed" }
|
||||
Pop-Location
|
40
.expeditor/buildkite/artifact.habitat.test.sh
Executable file
40
.expeditor/buildkite/artifact.habitat.test.sh
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -ueo pipefail
|
||||
|
||||
export HAB_ORIGIN='ci'
|
||||
export PLAN='inspec'
|
||||
export CHEF_LICENSE="accept-no-persist"
|
||||
export HAB_LICENSE="accept-no-persist"
|
||||
|
||||
echo "--- system details"
|
||||
uname -a
|
||||
|
||||
echo "--- Generating fake origin key"
|
||||
hab origin key generate $HAB_ORIGIN
|
||||
HAB_CI_KEY=$(realpath "$HOME"/.hab/cache/keys/"$HAB_ORIGIN"*.pub)
|
||||
export HAB_CI_KEY
|
||||
|
||||
echo "--- Building $PLAN"
|
||||
project_root="$(git rev-parse --show-toplevel)"
|
||||
cd "$project_root"
|
||||
|
||||
DO_CHECK=true hab pkg build .
|
||||
|
||||
echo "--- Sourcing 'results/last_build.sh'"
|
||||
if [ -f ./results/last_build.env ]; then
|
||||
. ./results/last_build.env
|
||||
export pkg_artifact
|
||||
fi
|
||||
|
||||
echo "+++ Installing ${pkg_ident:?is undefined}"
|
||||
|
||||
# habitat sudo install
|
||||
HSI="$project_root"/.expeditor/buildkite/artifact.habitat.install.sh
|
||||
|
||||
sudo -E "$HSI"
|
||||
|
||||
echo "+++ Testing $PLAN"
|
||||
pushd "$project_root/test/artifact"
|
||||
rake
|
||||
popd
|
|
@ -1,8 +1,27 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -ueo pipefail
|
||||
set -ue
|
||||
|
||||
echo "--- dependencies"
|
||||
export LANG=C.UTF-8 LANGUAGE=C.UTF-8
|
||||
S3_URL="s3://public-cd-buildkite-cache/${BUILDKITE_PIPELINE_SLUG}/${BUILDKITE_LABEL}"
|
||||
|
||||
pull_s3_file() {
|
||||
aws s3 cp "${S3_URL}/$1" "$1" || echo "Could not pull $1 from S3"
|
||||
}
|
||||
|
||||
push_s3_file() {
|
||||
if [ -f "$1" ]; then
|
||||
aws s3 cp "$1" "${S3_URL}/$1" || echo "Could not push $1 to S3 for caching."
|
||||
fi
|
||||
}
|
||||
|
||||
apt-get update -y
|
||||
apt-get install sudo awscli -y
|
||||
|
||||
echo "--- setting up user"
|
||||
useradd -m -U --uid 2000 normal
|
||||
echo "normal ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/normal
|
||||
|
||||
echo "--- updating rubygems"
|
||||
gem update --system -N
|
||||
|
@ -13,7 +32,33 @@ gem env
|
|||
bundle --version
|
||||
|
||||
echo "--- bundle install"
|
||||
pull_s3_file "bundle.tar.gz"
|
||||
pull_s3_file "bundle.sha256"
|
||||
|
||||
if [ -f bundle.tar.gz ]; then
|
||||
tar -xzf bundle.tar.gz
|
||||
fi
|
||||
|
||||
if [ -n "${RESET_BUNDLE_CACHE:-}" ]; then
|
||||
rm bundle.sha256
|
||||
fi
|
||||
|
||||
bundle config --local path vendor/bundle
|
||||
bundle install --jobs=7 --retry=3 --without tools maintenance deploy
|
||||
|
||||
echo "--- bundle cache"
|
||||
if test -f bundle.sha256 && shasum --check bundle.sha256 --status; then
|
||||
echo "Bundled gems have not changed. Skipping upload to s3"
|
||||
else
|
||||
echo "Bundled gems have changed. Uploading to s3"
|
||||
shasum -a 256 Gemfile.lock > bundle.sha256
|
||||
tar -czf bundle.tar.gz vendor/
|
||||
push_s3_file bundle.tar.gz
|
||||
push_s3_file bundle.sha256
|
||||
fi
|
||||
|
||||
echo "+++ bundle exec rake"
|
||||
# TODO: run this as non-root:
|
||||
# chown -R normal:normal /home/normal /workdir
|
||||
# su normal -c "bundle exec rake ${RAKE_TASK:-}"
|
||||
bundle exec rake ${RAKE_TASK:-}
|
||||
|
|
|
@ -33,7 +33,6 @@ pipelines:
|
|||
- N: 5
|
||||
- coverage:
|
||||
description: Generate test coverage report
|
||||
public: true
|
||||
env:
|
||||
- CI_ENABLE_COVERAGE: true
|
||||
- LANG: "C.UTF-8"
|
||||
|
@ -44,6 +43,9 @@ pipelines:
|
|||
- www/deploy:
|
||||
description: Deploy website to inspec.io
|
||||
definition: .expeditor/wwwdeploy.yml
|
||||
- integration/resources:
|
||||
description: Test core resources with test-kitchen.
|
||||
definition: .expeditor/integration.resources.yml
|
||||
- integration/libraries:
|
||||
description: Integration with plugins, gems, resource packs.
|
||||
definition: .expeditor/integration.libraries.yml
|
||||
|
@ -56,6 +58,9 @@ pipelines:
|
|||
- integration/automate:
|
||||
description: Integration with Chef Automate
|
||||
definition: .expeditor/integration.automate.yml
|
||||
- artifact/habitat:
|
||||
description: Execute tests against the habitat artifact
|
||||
definition: .expeditor/artifact.habitat.yml
|
||||
|
||||
schedules:
|
||||
- name: integration_schedule
|
||||
|
@ -164,3 +169,4 @@ subscriptions:
|
|||
only_if_team_member:
|
||||
- inspec/owners
|
||||
- inspec/inspec-core-team
|
||||
- post_github_comment:.expeditor/templates/pull_request.mustache
|
||||
|
|
1
.expeditor/integration.resources.yml
Normal file
1
.expeditor/integration.resources.yml
Normal file
|
@ -0,0 +1 @@
|
|||
#
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
set -eou pipefail
|
||||
|
||||
git clone https://github.com/inspec/inspec.wiki.git
|
||||
git clone https://x-access-token:${GITHUB_TOKEN}@github.com/inspec/inspec.wiki.git
|
||||
|
||||
pushd ./inspec.wiki
|
||||
# Publish release notes to S3
|
||||
|
|
|
@ -6,7 +6,7 @@ expeditor:
|
|||
retry:
|
||||
automatic:
|
||||
limit: 1
|
||||
|
||||
|
||||
steps:
|
||||
|
||||
- label: run-tests-ruby-2.4
|
||||
|
@ -33,6 +33,14 @@ steps:
|
|||
docker:
|
||||
image: ruby:2.6-stretch
|
||||
|
||||
- label: run-tests-ruby-2.7-preview
|
||||
command:
|
||||
- /workdir/.expeditor/buildkite/verify.sh || true
|
||||
expeditor:
|
||||
executor:
|
||||
docker:
|
||||
image: ruby:2.7-rc-buster
|
||||
|
||||
- label: isolated-tests-ruby-2.6
|
||||
command:
|
||||
- RAKE_TASK=test:isolated /workdir/.expeditor/buildkite/verify.sh
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
AllCops:
|
||||
Exclude:
|
||||
- 'test/kitchen/**/*'
|
||||
- 'test/integration/**/controls/**/*.rb'
|
||||
- 'test/unit/mock/profiles/**/*.rb'
|
||||
- 'test/unit/mock/config_dirs/**/*.rb'
|
||||
|
|
161
CHANGELOG.md
161
CHANGELOG.md
|
@ -1,47 +1,141 @@
|
|||
# Change Log
|
||||
<!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ -->
|
||||
<!-- latest_release 4.17.5 -->
|
||||
## [v4.17.5](https://github.com/inspec/inspec/tree/v4.17.5) (2019-09-25)
|
||||
<!-- latest_release unreleased -->
|
||||
## Unreleased
|
||||
|
||||
#### Merged Pull Requests
|
||||
- Split and parallelize some tests to make them faster [#4490](https://github.com/inspec/inspec/pull/4490) ([zenspider](https://github.com/zenspider))
|
||||
- Fix false positives on bundle caching check in buildkite. [#4660](https://github.com/inspec/inspec/pull/4660) ([zenspider](https://github.com/zenspider))
|
||||
<!-- latest_release -->
|
||||
|
||||
<!-- release_rollup since=4.16.0 -->
|
||||
### Changes since 4.16.0 release
|
||||
|
||||
#### Bug Fixes
|
||||
- Use File.realpath in Loader#plugin_gem_path to resolve all symlinks. [#4476](https://github.com/inspec/inspec/pull/4476) ([zenspider](https://github.com/zenspider)) <!-- 4.17.3 -->
|
||||
- Resolve issue where the Inspec::Tag to_ruby method outputs invalid Ruby [#4434](https://github.com/inspec/inspec/pull/4434) ([irvingpop](https://github.com/irvingpop)) <!-- 4.17.2 -->
|
||||
- Add to_s definitions to several resources [#4478](https://github.com/inspec/inspec/pull/4478) ([clintoncwolfe](https://github.com/clintoncwolfe)) <!-- 4.16.13 -->
|
||||
- Fix broken unit test by adding require [#4469](https://github.com/inspec/inspec/pull/4469) ([clintoncwolfe](https://github.com/clintoncwolfe)) <!-- 4.16.12 -->
|
||||
- Fixed file resource raising UndefinedMethod on source_path [#4214](https://github.com/inspec/inspec/pull/4214) ([zenspider](https://github.com/zenspider)) <!-- 4.16.1 -->
|
||||
<!-- release_rollup since=4.18.24 -->
|
||||
### Changes since 4.18.24 release
|
||||
|
||||
#### Merged Pull Requests
|
||||
- Split and parallelize some tests to make them faster [#4490](https://github.com/inspec/inspec/pull/4490) ([zenspider](https://github.com/zenspider)) <!-- 4.17.5 -->
|
||||
- Fixed MssqlSession.query not escaping double quote correctly [#4393](https://github.com/inspec/inspec/pull/4393) ([dalee-bis](https://github.com/dalee-bis)) <!-- 4.17.4 -->
|
||||
- Waivers Phase 3 [#4493](https://github.com/inspec/inspec/pull/4493) ([miah](https://github.com/miah)) <!-- 4.17.1 -->
|
||||
- Expand sys_info resource functionality [#4388](https://github.com/inspec/inspec/pull/4388) ([Vancelot11](https://github.com/Vancelot11)) <!-- 4.17.0 -->
|
||||
- Split out Inspec::Input functional code from the code generation code. [#4485](https://github.com/inspec/inspec/pull/4485) ([zenspider](https://github.com/zenspider)) <!-- 4.16.15 -->
|
||||
- Added test:isolate task that runs tests isolated but in parallel. [#4480](https://github.com/inspec/inspec/pull/4480) ([zenspider](https://github.com/zenspider)) <!-- 4.16.14 -->
|
||||
- Fix simple typo: becuase -> because [#4484](https://github.com/inspec/inspec/pull/4484) ([timgates42](https://github.com/timgates42)) <!-- 4.16.14 -->
|
||||
- Update rubygems and use gem env for system details. [#4475](https://github.com/inspec/inspec/pull/4475) ([zenspider](https://github.com/zenspider)) <!-- 4.16.13 -->
|
||||
- json resource: Add handling for `command:` error [#3844](https://github.com/inspec/inspec/pull/3844) ([jerryaldrichiii](https://github.com/jerryaldrichiii)) <!-- 4.16.11 -->
|
||||
- Rough draft on waiver input [#4437](https://github.com/inspec/inspec/pull/4437) ([zenspider](https://github.com/zenspider)) <!-- 4.16.10 -->
|
||||
- waivers: functional test fixture and eval-time skipping [#4427](https://github.com/inspec/inspec/pull/4427) ([clintoncwolfe](https://github.com/clintoncwolfe)) <!-- 4.16.9 -->
|
||||
- Make inspec much faster for most commands. [#4365](https://github.com/inspec/inspec/pull/4365) ([zenspider](https://github.com/zenspider)) <!-- 4.16.8 -->
|
||||
- Try to decode archive contents to UTF-8 to avoid encoding corruption. [#4451](https://github.com/inspec/inspec/pull/4451) ([zenspider](https://github.com/zenspider)) <!-- 4.16.7 -->
|
||||
- Fix for postfix_conf when using a non-standard config location [#4443](https://github.com/inspec/inspec/pull/4443) ([ramereth](https://github.com/ramereth)) <!-- 4.16.6 -->
|
||||
- Rework activator plugin to be more idiomatic. [#4446](https://github.com/inspec/inspec/pull/4446) ([zenspider](https://github.com/zenspider)) <!-- 4.16.5 -->
|
||||
- Clean up our use of SecureRandom in Rakefile. [#4447](https://github.com/inspec/inspec/pull/4447) ([zenspider](https://github.com/zenspider)) <!-- 4.16.4 -->
|
||||
- Guard against nil in apt repo parser. [#4435](https://github.com/inspec/inspec/pull/4435) ([zenspider](https://github.com/zenspider)) <!-- 4.16.4 -->
|
||||
- Fixed the formatting of `inspec exec -h` by not using long_desc. [#4436](https://github.com/inspec/inspec/pull/4436) ([zenspider](https://github.com/zenspider)) <!-- 4.16.3 -->
|
||||
- Extended skip_windows to the end of September. [#4441](https://github.com/inspec/inspec/pull/4441) ([zenspider](https://github.com/zenspider)) <!-- 4.16.2 -->
|
||||
- update LCR Roadtrip announcement to 13 cities [#4440](https://github.com/inspec/inspec/pull/4440) ([shaunyap](https://github.com/shaunyap)) <!-- 4.16.1 -->
|
||||
- Use new logo branding [#4433](https://github.com/inspec/inspec/pull/4433) ([btm](https://github.com/btm)) <!-- 4.16.0 -->
|
||||
- Fix false positives on bundle caching check in buildkite. [#4660](https://github.com/inspec/inspec/pull/4660) ([zenspider](https://github.com/zenspider)) <!-- 4.18.26 -->
|
||||
- Change "an Chef Inspec" to "a Chef Inspec". [#4663](https://github.com/inspec/inspec/pull/4663) ([kcrouch](https://github.com/kcrouch)) <!-- 4.18.26 -->
|
||||
- incorporate changes from chef hab plan [#4662](https://github.com/inspec/inspec/pull/4662) ([miah](https://github.com/miah)) <!-- 4.18.25 -->
|
||||
<!-- release_rollup -->
|
||||
|
||||
<!-- latest_stable_release -->
|
||||
## [v4.18.24](https://github.com/inspec/inspec/tree/v4.18.24) (2019-11-01)
|
||||
|
||||
#### Bug Fixes
|
||||
- Replace input to_hash method, and add unit test for it [#4545](https://github.com/inspec/inspec/pull/4545) ([clintoncwolfe](https://github.com/clintoncwolfe))
|
||||
- Fix TarProvider when the tarball has empty files in it. [#4619](https://github.com/inspec/inspec/pull/4619) ([zenspider](https://github.com/zenspider))
|
||||
- iis_app_pool better handling of non-existent pools. [#4636](https://github.com/inspec/inspec/pull/4636) ([miah](https://github.com/miah))
|
||||
- Fix filesystem resource when device has long name [#4637](https://github.com/inspec/inspec/pull/4637) ([miah](https://github.com/miah))
|
||||
- Add #to_s to etc_hosts_allow, and add tests [#4638](https://github.com/inspec/inspec/pull/4638) ([miah](https://github.com/miah))
|
||||
- Improve testing for yum.repo in CentOS 8 [#4568](https://github.com/inspec/inspec/pull/4568) ([ramereth](https://github.com/ramereth))
|
||||
- Fix config reference in `compliance exec` [#4650](https://github.com/inspec/inspec/pull/4650) ([clintoncwolfe](https://github.com/clintoncwolfe))
|
||||
|
||||
#### Merged Pull Requests
|
||||
- Telemetry: add chef-core [#4569](https://github.com/inspec/inspec/pull/4569) ([clintoncwolfe](https://github.com/clintoncwolfe))
|
||||
- Goodbye Gordon! [#4577](https://github.com/inspec/inspec/pull/4577) ([miah](https://github.com/miah))
|
||||
- Re-organize test-kitchen files. Add BK Pipeline [#4601](https://github.com/inspec/inspec/pull/4601) ([miah](https://github.com/miah))
|
||||
- Empty resources yml until I build it. [#4610](https://github.com/inspec/inspec/pull/4610) ([miah](https://github.com/miah))
|
||||
- Dont trigger yet [#4611](https://github.com/inspec/inspec/pull/4611) ([miah](https://github.com/miah))
|
||||
- Use a good profile with inspec check test [#4612](https://github.com/inspec/inspec/pull/4612) ([miah](https://github.com/miah))
|
||||
- Refactored and added an alternative test mock resource system. [#4566](https://github.com/inspec/inspec/pull/4566) ([zenspider](https://github.com/zenspider))
|
||||
- Make shell script executable [#4618](https://github.com/inspec/inspec/pull/4618) ([miah](https://github.com/miah))
|
||||
- Fix the path for our scripts, I don't know where I got /workdir [#4620](https://github.com/inspec/inspec/pull/4620) ([miah](https://github.com/miah))
|
||||
- Fix the search button wiring. [#4625](https://github.com/inspec/inspec/pull/4625) ([zenspider](https://github.com/zenspider))
|
||||
- Rescue SystemStackError to make errors during inspec check/archive more graceful. [#4597](https://github.com/inspec/inspec/pull/4597) ([zenspider](https://github.com/zenspider))
|
||||
- Clean up testing in inspec exec by stripping ansi color codes from output. [#4598](https://github.com/inspec/inspec/pull/4598) ([zenspider](https://github.com/zenspider))
|
||||
- JSON processing and resource cleanup [#4627](https://github.com/inspec/inspec/pull/4627) ([zenspider](https://github.com/zenspider))
|
||||
- Update waivers.md [#4631](https://github.com/inspec/inspec/pull/4631) ([larryebaum](https://github.com/larryebaum))
|
||||
- Add ruby 2.7 preview [#4600](https://github.com/inspec/inspec/pull/4600) ([miah](https://github.com/miah))
|
||||
- Fix a crash from users resource if the password has never been updated [#4635](https://github.com/inspec/inspec/pull/4635) ([zenspider](https://github.com/zenspider))
|
||||
- Create a user 'normal' and use it to run tests. Also bundle caching. [#4626](https://github.com/inspec/inspec/pull/4626) ([zenspider](https://github.com/zenspider))
|
||||
- Fixed the rest of the minitest deprecations by removing FuncTestRunResult. [#4628](https://github.com/inspec/inspec/pull/4628) ([zenspider](https://github.com/zenspider))
|
||||
- bumped the windows tests again [#4649](https://github.com/inspec/inspec/pull/4649) ([zenspider](https://github.com/zenspider))
|
||||
- Fix building the website [#4652](https://github.com/inspec/inspec/pull/4652) ([btm](https://github.com/btm))
|
||||
- Fixed problem with accessing backend in TestDslLazyLoader#method_missing. [#4648](https://github.com/inspec/inspec/pull/4648) ([zenspider](https://github.com/zenspider))
|
||||
- oracledb_session fixes [#4654](https://github.com/inspec/inspec/pull/4654) ([miah](https://github.com/miah))
|
||||
- Nginx Resource: Add parsing support for wildcard, dot prefix, and regex [#4653](https://github.com/inspec/inspec/pull/4653) ([landychan](https://github.com/landychan))
|
||||
- Ooops. I didn't need to remove this just yet. html parser is using it. [#4658](https://github.com/inspec/inspec/pull/4658) ([miah](https://github.com/miah))
|
||||
- Fixed runner tests for windows. [#4659](https://github.com/inspec/inspec/pull/4659) ([zenspider](https://github.com/zenspider))
|
||||
<!-- latest_stable_release -->
|
||||
|
||||
## [v4.18.0](https://github.com/inspec/inspec/tree/v4.18.0) (2019-10-10)
|
||||
|
||||
#### Bug Fixes
|
||||
- Fix problem in method_missing in rspec extensions when backend unavailable. [#4565](https://github.com/inspec/inspec/pull/4565) ([zenspider](https://github.com/zenspider))
|
||||
|
||||
#### Merged Pull Requests
|
||||
- Fixed tests to work with rspec-expectations 3.8.5+. [#4557](https://github.com/inspec/inspec/pull/4557) ([zenspider](https://github.com/zenspider))
|
||||
- First pass at cleaning deprecations for old minitest/spec-style tests. [#4563](https://github.com/inspec/inspec/pull/4563) ([zenspider](https://github.com/zenspider))
|
||||
- Fixed apt resource incorrectly parsing deb files w/ quoted URIs. [#4560](https://github.com/inspec/inspec/pull/4560) ([zenspider](https://github.com/zenspider))
|
||||
- Missing require for EnvPrinter means `inspec env` stacktraced. [#4554](https://github.com/inspec/inspec/pull/4554) ([miah](https://github.com/miah))
|
||||
- Add name property to interface resource [#4558](https://github.com/inspec/inspec/pull/4558) ([miah](https://github.com/miah))
|
||||
- Remove unused polyfill.rb file adding to_h to Struct [#4553](https://github.com/inspec/inspec/pull/4553) ([miah](https://github.com/miah))
|
||||
- Don't use #at when you can use #[] for array (or hash) access. [#4556](https://github.com/inspec/inspec/pull/4556) ([zenspider](https://github.com/zenspider))
|
||||
- User windows fix [#4452](https://github.com/inspec/inspec/pull/4452) ([mhackethal](https://github.com/mhackethal))
|
||||
- Pin RSpec to 3.8.6 to avoid test failures for now [#4576](https://github.com/inspec/inspec/pull/4576) ([clintoncwolfe](https://github.com/clintoncwolfe))
|
||||
- Waivers Feedback - Per control reporting and other minor issues [#4567](https://github.com/inspec/inspec/pull/4567) ([clintoncwolfe](https://github.com/clintoncwolfe))
|
||||
|
||||
## [v4.17.17](https://github.com/inspec/inspec/tree/v4.17.17) (2019-10-03)
|
||||
|
||||
#### Merged Pull Requests
|
||||
- Added method_missing to Inspec::DescribeBase (used by describe.one) to fix resource loading [#4549](https://github.com/inspec/inspec/pull/4549) ([zenspider](https://github.com/zenspider))
|
||||
- Add no-op resource and switch Rule to use it for skipped resources. [#4550](https://github.com/inspec/inspec/pull/4550) ([zenspider](https://github.com/zenspider))
|
||||
|
||||
## [v4.17.15](https://github.com/inspec/inspec/tree/v4.17.15) (2019-10-01)
|
||||
|
||||
#### Merged Pull Requests
|
||||
- Pass access token [#4544](https://github.com/inspec/inspec/pull/4544) ([miah](https://github.com/miah))
|
||||
- Fix config clearing [#4483](https://github.com/inspec/inspec/pull/4483) ([frezbo](https://github.com/frezbo))
|
||||
|
||||
## [v4.17.14](https://github.com/inspec/inspec/tree/v4.17.14) (2019-09-30)
|
||||
|
||||
#### Bug Fixes
|
||||
- Add resource stub for sshd_config [#4538](https://github.com/inspec/inspec/pull/4538) ([clintoncwolfe](https://github.com/clintoncwolfe))
|
||||
- Add missing resource stubs for 'group' resource [#4537](https://github.com/inspec/inspec/pull/4537) ([baurmatt](https://github.com/baurmatt))
|
||||
|
||||
#### Merged Pull Requests
|
||||
- Yet another bump of our skip_windows! due date. [#4540](https://github.com/inspec/inspec/pull/4540) ([zenspider](https://github.com/zenspider))
|
||||
|
||||
## [v4.17.11](https://github.com/inspec/inspec/tree/v4.17.11) (2019-09-28)
|
||||
|
||||
#### Merged Pull Requests
|
||||
- Remove maintainers task from require [#4531](https://github.com/inspec/inspec/pull/4531) ([miah](https://github.com/miah))
|
||||
- Add resource stubs so the resource loader will find all resources [#4526](https://github.com/inspec/inspec/pull/4526) ([clintoncwolfe](https://github.com/clintoncwolfe))
|
||||
- Fixed inspec lazy resource loader for rspec test dsl (eg before/after) [#4534](https://github.com/inspec/inspec/pull/4534) ([zenspider](https://github.com/zenspider))
|
||||
- fix Gemfile for inspec-core-bin gem [#4535](https://github.com/inspec/inspec/pull/4535) ([lamont-granquist](https://github.com/lamont-granquist))
|
||||
|
||||
## [v4.17.7](https://github.com/inspec/inspec/tree/v4.17.7) (2019-09-27)
|
||||
|
||||
#### Bug Fixes
|
||||
- Fixed file resource raising UndefinedMethod on source_path [#4214](https://github.com/inspec/inspec/pull/4214) ([zenspider](https://github.com/zenspider))
|
||||
- Fix broken unit test by adding require [#4469](https://github.com/inspec/inspec/pull/4469) ([clintoncwolfe](https://github.com/clintoncwolfe))
|
||||
- Add to_s definitions to several resources [#4478](https://github.com/inspec/inspec/pull/4478) ([clintoncwolfe](https://github.com/clintoncwolfe))
|
||||
- Resolve issue where the Inspec::Tag to_ruby method outputs invalid Ruby [#4434](https://github.com/inspec/inspec/pull/4434) ([irvingpop](https://github.com/irvingpop))
|
||||
- Use File.realpath in Loader#plugin_gem_path to resolve all symlinks. [#4476](https://github.com/inspec/inspec/pull/4476) ([zenspider](https://github.com/zenspider))
|
||||
|
||||
#### Merged Pull Requests
|
||||
- Use new logo branding [#4433](https://github.com/inspec/inspec/pull/4433) ([btm](https://github.com/btm))
|
||||
- update LCR Roadtrip announcement to 13 cities [#4440](https://github.com/inspec/inspec/pull/4440) ([shaunyap](https://github.com/shaunyap))
|
||||
- Extended skip_windows to the end of September. [#4441](https://github.com/inspec/inspec/pull/4441) ([zenspider](https://github.com/zenspider))
|
||||
- Fixed the formatting of `inspec exec -h` by not using long_desc. [#4436](https://github.com/inspec/inspec/pull/4436) ([zenspider](https://github.com/zenspider))
|
||||
- Guard against nil in apt repo parser. [#4435](https://github.com/inspec/inspec/pull/4435) ([zenspider](https://github.com/zenspider))
|
||||
- Clean up our use of SecureRandom in Rakefile. [#4447](https://github.com/inspec/inspec/pull/4447) ([zenspider](https://github.com/zenspider))
|
||||
- Rework activator plugin to be more idiomatic. [#4446](https://github.com/inspec/inspec/pull/4446) ([zenspider](https://github.com/zenspider))
|
||||
- Fix for postfix_conf when using a non-standard config location [#4443](https://github.com/inspec/inspec/pull/4443) ([ramereth](https://github.com/ramereth))
|
||||
- Try to decode archive contents to UTF-8 to avoid encoding corruption. [#4451](https://github.com/inspec/inspec/pull/4451) ([zenspider](https://github.com/zenspider))
|
||||
- Make inspec much faster for most commands. [#4365](https://github.com/inspec/inspec/pull/4365) ([zenspider](https://github.com/zenspider))
|
||||
- waivers: functional test fixture and eval-time skipping [#4427](https://github.com/inspec/inspec/pull/4427) ([clintoncwolfe](https://github.com/clintoncwolfe))
|
||||
- Rough draft on waiver input [#4437](https://github.com/inspec/inspec/pull/4437) ([zenspider](https://github.com/zenspider))
|
||||
- json resource: Add handling for `command:` error [#3844](https://github.com/inspec/inspec/pull/3844) ([jerryaldrichiii](https://github.com/jerryaldrichiii))
|
||||
- Update rubygems and use gem env for system details. [#4475](https://github.com/inspec/inspec/pull/4475) ([zenspider](https://github.com/zenspider))
|
||||
- Fix simple typo: becuase -> because [#4484](https://github.com/inspec/inspec/pull/4484) ([timgates42](https://github.com/timgates42))
|
||||
- Added test:isolate task that runs tests isolated but in parallel. [#4480](https://github.com/inspec/inspec/pull/4480) ([zenspider](https://github.com/zenspider))
|
||||
- Split out Inspec::Input functional code from the code generation code. [#4485](https://github.com/inspec/inspec/pull/4485) ([zenspider](https://github.com/zenspider))
|
||||
- Expand sys_info resource functionality [#4388](https://github.com/inspec/inspec/pull/4388) ([Vancelot11](https://github.com/Vancelot11))
|
||||
- Waivers Phase 3 [#4493](https://github.com/inspec/inspec/pull/4493) ([miah](https://github.com/miah))
|
||||
- Fixed MssqlSession.query not escaping double quote correctly [#4393](https://github.com/inspec/inspec/pull/4393) ([dalee-bis](https://github.com/dalee-bis))
|
||||
- Split and parallelize some tests to make them faster [#4490](https://github.com/inspec/inspec/pull/4490) ([zenspider](https://github.com/zenspider))
|
||||
- Fixed Inspec::Plugin::V2::Registry#detect_system_plugins [#4513](https://github.com/inspec/inspec/pull/4513) ([zenspider](https://github.com/zenspider))
|
||||
- Added first draft of waiver doco. [#4518](https://github.com/inspec/inspec/pull/4518) ([zenspider](https://github.com/zenspider))
|
||||
|
||||
## [v4.16.0](https://github.com/inspec/inspec/tree/v4.16.0) (2019-08-29)
|
||||
|
||||
#### New Resources
|
||||
|
@ -65,7 +159,6 @@
|
|||
- Remove inspec-vault from the plugin exclusion list [#4411](https://github.com/inspec/inspec/pull/4411) ([clintoncwolfe](https://github.com/clintoncwolfe))
|
||||
- Let expeditor respond to pull requests. [#4430](https://github.com/inspec/inspec/pull/4430) ([miah](https://github.com/miah))
|
||||
- Deprecate macOS 10.12 and add macOS 10.15 support [#4421](https://github.com/inspec/inspec/pull/4421) ([jaymalasinha](https://github.com/jaymalasinha))
|
||||
<!-- latest_stable_release -->
|
||||
|
||||
## [v4.12.0](https://github.com/inspec/inspec/tree/v4.12.0) (2019-08-15)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ FROM ruby:alpine
|
|||
LABEL maintainer="Chef Software, Inc. <docker@chef.io>"
|
||||
|
||||
ARG EXPEDITOR_VERSION
|
||||
ARG VERSION=4.16.0
|
||||
ARG VERSION=4.18.24
|
||||
ARG GEM_SOURCE=https://rubygems.org
|
||||
|
||||
# Allow VERSION below to be controlled by either VERSION or EXPEDITOR_VERSION build arguments
|
||||
|
|
2
Rakefile
2
Rakefile
|
@ -4,7 +4,7 @@ require "bundler"
|
|||
require "bundler/gem_helper"
|
||||
require "rake/testtask"
|
||||
require "train"
|
||||
require_relative "tasks/maintainers"
|
||||
# require_relative "tasks/maintainers" # TODO: bring back after we push faraday_middleware fix upstream
|
||||
require_relative "tasks/spdx"
|
||||
require "fileutils"
|
||||
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
4.17.5
|
||||
4.18.26
|
120
docs/dev/compliance.md
Normal file
120
docs/dev/compliance.md
Normal file
|
@ -0,0 +1,120 @@
|
|||
# About `inspec compliance`
|
||||
|
||||
## 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.
|
||||
|
||||
`inspec compliance` 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.
|
||||
|
||||
## Operational Notes
|
||||
|
||||
### Obtaining an a test Automate server
|
||||
|
||||
You'll need a test Chef Automate server. https://learn.chef.io/modules/try-chef-automate#/setup is one way of setting one up locally.
|
||||
|
||||
### Getting an API token
|
||||
|
||||
After starting Automate, registering, and starting a trial license, you will need to setup an API token. You will use API token with `login`, which is required for most other commands. To setup an API token within the Automate UI:
|
||||
|
||||
1. Click the "Settings" tab. A new set of menus appears on the left.
|
||||
2. Choose "API Tokens" from the left menu.
|
||||
3. Create a new API token. Your choice of name and ID don't really matter. After creation, select the new token, click the three dots to reveal the extended menu, and choose "Copy Token".
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### Code Location
|
||||
|
||||
#### as a CLI command plugin
|
||||
|
||||
The codebase is located in `inspec/lib/plugins/inspec-compliance/`. It is a minimally converted v2 plugin, meaning that it works fine as a plugin but little was done to clean it up.
|
||||
|
||||
#### Legacy external require location for audit cookbook
|
||||
|
||||
The audit cookbook requires in the compliance plugin, using a legacy path at `inspec/lib/bundles/inspec-compliance`. There are several stub files at that location. Because we cannot control which combination of inspec and audit cookbook are being used, even if we removed or updated the location in audit cookbook, we'd still need to leave the old stubs for a while.
|
||||
|
||||
### Important files
|
||||
|
||||
#### lib/cli.rb
|
||||
|
||||
This file defines the Thor subcommand CLI UX. Look at this file for all commands and options. Most command implementation is right here inline, which makes this file large and noisy. Some implementation, pertaining to interaction with the actual Automate service, is pushed out to a class `InspecPlugins::Compliance::API`; class methods are used to perform actions.
|
||||
|
||||
#### lib/configuration.rb
|
||||
|
||||
A fairly straightforward data container with JSON marshalling. Used to store CLI options as well as to write credentials to disk.
|
||||
|
||||
#### lib/api.rb
|
||||
|
||||
This is the wrapper around the Automate API. The approach is to present class methods which take as an argument a stateful config object.
|
||||
The code is brittle, being highly conditionalized for products that have been sunsetted, such as Compliance and the soon to sunsetted Automate1. In some cases there are conditionals for versions that have been sunsetted as well.
|
||||
|
||||
Actual HTTP communication is handled by `InspecPlugins::Compliance::HTTP`, again using class methods.
|
||||
|
||||
#### 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.
|
||||
|
||||
#### lib/support.rb
|
||||
|
||||
Tries to map versions to feature support for the API. Does not appear to be relied on very much. Duplicate functionality may be in lib/configuration.rb .
|
||||
|
||||
## Subcommands
|
||||
|
||||
There are several other minor commands not listed here - see `lib/cli.rb` for a complete listing.
|
||||
|
||||
### login
|
||||
|
||||
Saves a credentials file locally. Future invocations of `inspec compliance` use the credentials file to authenticate.
|
||||
|
||||
`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`:
|
||||
|
||||
```json
|
||||
{
|
||||
"automate": {
|
||||
"ent": "automate",
|
||||
"token_type": "dctoken"
|
||||
},
|
||||
"server": "https://chef-automate.test/api/v0",
|
||||
"user": "admin",
|
||||
"owner": "admin",
|
||||
"insecure": true,
|
||||
"server_type": "automate2",
|
||||
"token": "1234567890asdfghjkl",
|
||||
"version": "0"
|
||||
}
|
||||
```
|
||||
|
||||
#### login code trace
|
||||
|
||||
Thor code in `lib/cli.rb` stores the passed-in server URL in the config object, and then passes everything to `InspecPlugins::Compliance::API.login`. That class method is actually defined in `lib/api/login.rb` and is quite large because it immediately conditionalizes on supporting three products - Compliance, A1, and A2.
|
||||
|
||||
Next, the options passed in are lightly validated. A config object is created and the creds are stored, then saved to disk as JSON.
|
||||
|
||||
NOTE: At no point are the credentials tested by attempting to reach the Automate server (https://github.com/inspec/inspec/issues/3535). Learn Chef Rally materials suggest using the `profiles` command to verify your creds.
|
||||
|
||||
### profiles
|
||||
|
||||
Lists available profiles on the Automate server. Appears to only list those that have been "activated" (you have clicked "get" in the Automate UI). Uses the Inspec::UI code via the legacy calling patterns.
|
||||
|
||||
#### profile code trace
|
||||
|
||||
First, a new Config object is created, which reads the config from disk. Then, `loggedin(config)` is called, which does a very thin check - it only determines if a setting is present in the config for the server URL, but it does not actually contact the server. Finally, `InspecPlugins::Compliance::API.profiles` is called with the config, and with a lot of conditional logic, eventually returns a hash of profile metadata, which gets parsed and displayed.
|
||||
|
||||
### upload
|
||||
|
||||
Like knife cookbook upload, this command sends an artifact to be stored for retrieval by other clients. Chef Automate then runs `inspec check` on the profile on the server side, and if OK, stores the profile. The new profile is included in the list when running `profiles`.
|
||||
|
||||
#### upload code trace
|
||||
|
||||
Calls `vendor_deps()` from `inspec/lib/base_cli.rb` (OUTSIDE the plugin) - this vendors the profile.
|
||||
Checks the profile. The way that the errors in the profile are traced is unusual; it's accumulated using a lambda.
|
||||
Tar up the profile if it a directory.
|
||||
Calls `InspecPlugins::Compliance::API.upload` which, after conditionalizing on the URL and headers, does a POST.
|
||||
|
||||
### exec
|
||||
|
||||
Simply adds the `compliance://` schema to the beginning of the profile name then performs a normal run.
|
||||
Apparently there is a fetcher that can handle that, but I have not found that yet.
|
|
@ -54,7 +54,7 @@ where
|
|||
* `tag` is optional meta-information with with key or key-value pairs
|
||||
* `ref` is a reference to an external document
|
||||
* `describe` is a block that contains at least one test. A `control` block must contain at least one `describe` block, but may contain as many as required
|
||||
* `sshd_config` is an Chef InSpec resource. For the full list of Chef InSpec resources, see Chef InSpec resource documentation
|
||||
* `sshd_config` is a Chef InSpec resource. For the full list of Chef InSpec resources, see Chef InSpec resource documentation
|
||||
* `its('Port')` is the matcher; `{ should eq '22' }` is the test. A `describe` block must contain at least one matcher, but may contain as many as required
|
||||
|
||||
## Advanced concepts
|
||||
|
@ -272,7 +272,7 @@ end
|
|||
```
|
||||
|
||||
Ruby allows a lot of freedoms, but should be limited in controls so that they
|
||||
remain portable and easy to understand. Please see our [profile style guide](./style).
|
||||
remain portable and easy to understand. Please see our [profile style guide](https://www.inspec.io/docs/reference/style/).
|
||||
|
||||
Core and custom resources are written as regular Ruby classes which inherit from
|
||||
`Inspec.resource`.
|
||||
|
@ -280,8 +280,8 @@ Core and custom resources are written as regular Ruby classes which inherit from
|
|||
|
||||
## Interactive Debugging with Pry
|
||||
|
||||
Here's a sample Chef InSpec control that users Ruby variables to instantiate
|
||||
an Chef InSpec resource once and use the content in multiple tests.
|
||||
Here's a sample Chef InSpec control that uses Ruby variables to instantiate
|
||||
a Chef InSpec resource once and use the content in multiple tests.
|
||||
|
||||
```ruby
|
||||
control 'check-perl' do
|
||||
|
@ -340,10 +340,10 @@ $ inspec shell
|
|||
Welcome to the interactive InSpec Shell
|
||||
To find out how to use it, type: help
|
||||
|
||||
inspec> command('ls /home/gordon/git/inspec/docs').stdout
|
||||
=> "ctl_inspec.rst\ndsl_inspec.rst\ndsl_resource.rst\n"
|
||||
inspec> command('ls').stdout.split("\n")
|
||||
=> ["ctl_inspec.rst", "dsl_inspec.rst", "dsl_resource.rst"]
|
||||
inspec> command('ls ~/projects/github/inspec/docs').stdout
|
||||
=> "README.md\nconfig.md\ndev\ndsl_inspec.md\ndsl_resource.md\nglossary.md\nhabitat.md\ninputs.md\ninspec_and_friends.md\nmatchers.md\nmigration.md\nplatforms.md\nplugin_kitchen_inspec.md\nplugins.md\nprofiles.md\nreporters.md\nresources\nshared\nshell.md\nstyle.md\nwaivers.md\n"
|
||||
inspec> command('ls ~/projects/github/inspec/docs').stdout.split("\n").first
|
||||
=> "README.md"
|
||||
|
||||
inspec> help command
|
||||
Name: command
|
||||
|
|
|
@ -17,7 +17,7 @@ $ tree examples/profile
|
|||
examples/profile
|
||||
...
|
||||
├── libraries
|
||||
│ └── gordon_config.rb
|
||||
│ └── example_config.rb
|
||||
```
|
||||
|
||||
## Resource structure
|
||||
|
@ -51,8 +51,8 @@ The following example shows a full resource using attributes and methods
|
|||
to provide simple access to a configuration file:
|
||||
|
||||
```ruby
|
||||
class GordonConfig < Inspec.resource(1)
|
||||
name 'gordon_config'
|
||||
class ExampleConfig < Inspec.resource(1)
|
||||
name 'example_config'
|
||||
|
||||
# Restrict to only run on the below platforms (if none were given, all OS's supported)
|
||||
supports platform_family: 'fedora'
|
||||
|
@ -65,14 +65,14 @@ class GordonConfig < Inspec.resource(1)
|
|||
'
|
||||
|
||||
example '
|
||||
describe gordon_config do
|
||||
describe example_config do
|
||||
its("signal") { should eq "on" }
|
||||
end
|
||||
'
|
||||
|
||||
# Load the configuration file on initialization
|
||||
def initialize(path = nil)
|
||||
@path = path || '/etc/gordon.conf'
|
||||
@path = path || '/etc/example.conf'
|
||||
@params = SimpleConfig.new( read_content )
|
||||
end
|
||||
|
||||
|
@ -90,11 +90,40 @@ class GordonConfig < Inspec.resource(1)
|
|||
# Retrieve the file's contents
|
||||
f.content
|
||||
else
|
||||
# If the file doesn't exist, skip all tests that use gordon_config
|
||||
# If the file doesn't exist, skip all tests that use example_config
|
||||
raise Inspec::Exceptions::ResourceSkipped, "Can't read config at #{@path}"
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
For a full example, see our [example resource](https://github.com/chef/inspec/blob/master/examples/profile/libraries/gordon_config.rb).
|
||||
For a full example, see our [example resource](https://github.com/chef/inspec/blob/master/examples/profile/libraries/example_config.rb).
|
||||
|
||||
## Lazy Loading
|
||||
|
||||
Prior to InSpec v4.16, resources were pre-loaded for every invocation
|
||||
of `inspec`. This was a heavy and unnecessary burden on the system and
|
||||
exacerbated startup times (especially on Windows).
|
||||
|
||||
As of InSpec v4.16, resources are lazily loaded into the `inspec`
|
||||
process upon use. This greatly speeds up the initial startup costs of
|
||||
the `inspec` process and only loads what you need to use. For example, `inspec
|
||||
--version` no longer runs for 10 seconds!.
|
||||
|
||||
### Overriding Core Resources
|
||||
|
||||
Lazy loading does change the way the resource registry is handled in
|
||||
ways that might break some assumptions. Specifically,
|
||||
`inspec.<resource>` isn't pre-populated with the core resources that
|
||||
InSpec ships with. If you make a local/custom resource of the same
|
||||
name, referring to the core resource via `inspec.<resource>` will not
|
||||
resolve to the core resource.
|
||||
|
||||
As such, overriding core resources is not recommended best practice.
|
||||
|
||||
If you really do need to do this, it is easiest to make a local
|
||||
resource with a new name and refer to the core resource directly.
|
||||
Otherwise, you need to ensure that the core resource you want is
|
||||
registered (via `require "inspec/resource/<name>"`) _before_ your
|
||||
profile is run to ensure it is eagerly loaded and in the global
|
||||
resource registry.
|
||||
|
|
|
@ -128,7 +128,7 @@ A [resource](#resource) that is _not_ included with InSpec. It may be a resource
|
|||
|
||||
### describe block
|
||||
|
||||
The _`describe`_ keyword is used with a _`describe block`_ to refer to an 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.
|
||||
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
|
||||
control 'Rule 1.1 - Color restrictions' do
|
||||
|
@ -384,4 +384,4 @@ Here, we access the 'color' property, then use the `cmp` universal matcher to co
|
|||
describe car(owner: 'Bruce Wayne') do
|
||||
its('color') { should cmp 'black' }
|
||||
end
|
||||
```
|
||||
```
|
||||
|
|
|
@ -4,7 +4,7 @@ title: Chef InSpec Integration with Chef Habitat
|
|||
|
||||
# Chef Habitat Integration
|
||||
|
||||
Chef InSpec provides an easy method to create an executable Chef Habitat package for an Chef InSpec profile. When run via the Chef Habitat Supervisor, the package will run Chef InSpec with your profile and write out its findings to the supervisor log. This provides the ability to ship your compliance controls alongside your Chef Habitat-packaged application and continuously run InSpec, providing you *Continuous Compliance.*
|
||||
Chef InSpec provides an easy method to create an executable Chef Habitat package for a Chef InSpec profile. When run via the Chef Habitat Supervisor, the package will run Chef InSpec with your profile and write out its findings to the supervisor log. This provides the ability to ship your compliance controls alongside your Chef Habitat-packaged application and continuously run InSpec, providing you *Continuous Compliance.*
|
||||
|
||||
## What is Chef Habitat
|
||||
|
||||
|
@ -14,7 +14,7 @@ To learn more about Chef Habitat and try our demos and tutorials, visit [https:/
|
|||
|
||||
## Using the Chef Habitat Integration
|
||||
|
||||
After creating a Chef Habitat package for an Chef InSpec profile (see CLI commands below) and uploading the package to a Chef Habitat Depot or manually distributing to a host, start the Chef Habitat Supervisor with your package:
|
||||
After creating a Chef Habitat package for a Chef InSpec profile (see CLI commands below) and uploading the package to a Chef Habitat Depot or manually distributing to a host, start the Chef Habitat Supervisor with your package:
|
||||
|
||||
```bash
|
||||
hab start effortless/audit-baseline
|
||||
|
@ -70,7 +70,7 @@ Chef InSpec will write a JSON file in the `${svc_var_path}/inspec_results` direc
|
|||
|
||||
### inspec habitat profile create
|
||||
|
||||
Create a Chef Habitat package for an Chef InSpec profile. Chef InSpec will validate the profile, fetch and vendor any dependencies (if necessary), and build the Chef Habitat package with a dependency on the latest InSpec. The resulting package will be saved to the current working directory.
|
||||
Create a Chef Habitat package for a Chef InSpec profile. Chef InSpec will validate the profile, fetch and vendor any dependencies (if necessary), and build the Chef Habitat package with a dependency on the latest InSpec. The resulting package will be saved to the current working directory.
|
||||
|
||||
The package can then be manually uploaded to a Chef Habitat Depot or manually distributed to a host and installed via `hab pkg install`.
|
||||
|
||||
|
@ -154,7 +154,7 @@ inspec habitat profile setup ~/profiles/frontend1
|
|||
|
||||
### inspec habitat profile upload
|
||||
|
||||
Create and then upload a Chef Habitat package for an Chef InSpec profile. Like the `inspec habitat profile create` command, Chef InSpec will validate the profile, fetch and vendor any dependencies (if necessary), and build the Chef Habitat package with a dependency on the latest InSpec. However, instead of saving the package locally to the workstation, Chef InSpec will upload it to the depot defined in the `HAB_DEPOT` environment variable. If `HAB_DEPOT` is not defined, the package will be uploaded to the public Chef Habitat depot at [https://app.habitat.sh](https://app.habitat.sh).
|
||||
Create and then upload a Chef Habitat package for a Chef InSpec profile. Like the `inspec habitat profile create` command, Chef InSpec will validate the profile, fetch and vendor any dependencies (if necessary), and build the Chef Habitat package with a dependency on the latest InSpec. However, instead of saving the package locally to the workstation, Chef InSpec will upload it to the depot defined in the `HAB_DEPOT` environment variable. If `HAB_DEPOT` is not defined, the package will be uploaded to the public Chef Habitat depot at [https://app.habitat.sh](https://app.habitat.sh).
|
||||
|
||||
#### Syntax
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ For more details on what the `plugin` command can do, see the [online help](http
|
|||
|
||||
### Chef InSpec Plugins
|
||||
|
||||
For details on how to author an Chef InSpec Plugin, see the [developer documentation](https://github.com/inspec/inspec/blob/master/docs/dev/plugins.md)
|
||||
For details on how to author a Chef InSpec Plugin, see the [developer documentation](https://github.com/inspec/inspec/blob/master/docs/dev/plugins.md)
|
||||
|
||||
### Train Plugins
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ supports:
|
|||
|
||||
# Profile Dependencies
|
||||
|
||||
An Chef InSpec profile can bring in the controls and custom resources from another Chef InSpec profile. Additionally, when inheriting the controls of another profile, a profile can skip or even modify those included controls.
|
||||
A Chef InSpec profile can bring in the controls and custom resources from another Chef InSpec profile. Additionally, when inheriting the controls of another profile, a profile can skip or even modify those included controls.
|
||||
|
||||
For hands-on examples, check out [Create a custom Chef InSpec profile](https://learn.chef.io/modules/create-a-custom-profile#/) on Learn Chef Rally.
|
||||
|
||||
|
@ -336,11 +336,11 @@ profile `my_dep` using the name `my_res2`.
|
|||
|
||||
# Profile Inputs
|
||||
|
||||
Our documentation regarding [Inputs](docs/reference/inputs/) is now on a dedicated page.
|
||||
Our documentation regarding [Inputs](https://www.inspec.io/docs/reference/inputs/) is now on a dedicated page.
|
||||
|
||||
# Profile files
|
||||
|
||||
An Chef InSpec profile may contain additional files that can be accessed during tests. A profile file enables you to separate the logic of your tests from the data your tests check for, for example, the list of ports you require to be open.
|
||||
A Chef InSpec profile may contain additional files that can be accessed during tests. A profile file enables you to separate the logic of your tests from the data your tests check for, for example, the list of ports you require to be open.
|
||||
|
||||
To access these files, they must be stored in the `files` directory at the root of a profile. They are accessed by their name relative to this folder with `inspec.profile.file(...)`.
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ title: Chef InSpec Reporters
|
|||
|
||||
Introduced in Chef InSpec 1.51.6
|
||||
|
||||
A `reporter` is a facility for formatting and delivering the results of an Chef InSpec auditing run.
|
||||
A `reporter` is a facility for formatting and delivering the results of a Chef InSpec auditing run.
|
||||
|
||||
Chef InSpec allows you to output your test results to one or more reporters. Configure the reporter(s) using either the `--reporter` option or as part of the general config file using the `--config` (or `--json-config`, prior to v3.6) option. While you can configure multiple reporters to write to different files, only one reporter can output to the screen(stdout).
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ The following examples show how to use this Chef InSpec audit resource.
|
|||
end
|
||||
|
||||
describe ssh_config do
|
||||
its('SendEnv') { should include('GORDON_CLIENT') }
|
||||
its('SendEnv') { should include('CI_ENABLE_COVERAGE') }
|
||||
end
|
||||
|
||||
### Test SSH configuration
|
||||
|
|
|
@ -42,7 +42,7 @@ The following examples show how to use this Chef InSpec audit resource.
|
|||
### Test which variables may be sent to the server
|
||||
|
||||
describe sshd_config do
|
||||
its('AcceptEnv') { should include('GORDON_SERVER') }
|
||||
its('AcceptEnv') { should include('CI_ENABLE_COVERAGE') }
|
||||
end
|
||||
|
||||
### Test for IPv6-only addresses
|
||||
|
|
|
@ -34,13 +34,16 @@ A `user` resource block declares a user name, and then one (or more) matchers:
|
|||
its('mindays') { should eq 0 }
|
||||
its('maxdays') { should eq 90 }
|
||||
its('warndays') { should eq 8 }
|
||||
its('passwordage') { should eq 355 }
|
||||
its('maxbadpasswords') { should eq nil } // Only valid on Windows OS
|
||||
its('badpasswordattempts') { should eq 0 }
|
||||
end
|
||||
|
||||
where
|
||||
|
||||
* `('root')` is the user to be tested
|
||||
* `it { should exist }` tests if the user exists
|
||||
* `gid`, `group`, `groups`, `home`, `maxdays`, `mindays`, `shell`, `uid`, and `warndays` are valid matchers for this resource
|
||||
* `gid`, `group`, `groups`, `home`, `maxdays`, `mindays`, `shell`, `uid`, `warndays`´, `passwordage`, `maxbadpasswords` and `badpasswordattempts` are valid matchers for this resource
|
||||
|
||||
<br>
|
||||
|
||||
|
@ -90,6 +93,7 @@ The `gid` matcher tests the group identifier:
|
|||
its('gid') { should eq 1234 }
|
||||
|
||||
where `1234` represents the user identifier.
|
||||
The `gid` option is only available on Linux and will return `nil` for Windows os.
|
||||
|
||||
### group
|
||||
|
||||
|
@ -98,6 +102,7 @@ The `group` matcher tests the group to which the user belongs:
|
|||
its('group') { should eq 'root' }
|
||||
|
||||
where `root` represents the group.
|
||||
The `group` option is only available on Linux and will return `nil` for Windows os.
|
||||
|
||||
### groups
|
||||
|
||||
|
@ -148,3 +153,29 @@ The `warndays` matcher tests the number of days a user is warned before a passwo
|
|||
its('warndays') { should eq 5 }
|
||||
|
||||
where `5` represents the number of days a user is warned.
|
||||
|
||||
### passwordage
|
||||
|
||||
The `passwordage` matcher tests the number of days a user changed its password:
|
||||
|
||||
its('passwordage') { should_be <= 365 }
|
||||
|
||||
where `365` represents the number of days since the last password change.
|
||||
|
||||
### maxbadpasswords
|
||||
|
||||
The `maxbadpasswords` matcher tests the count of max badpassword settings for a specific user.
|
||||
|
||||
its('maxbadpasswords') { should eq 7 }
|
||||
|
||||
where `7` is the count of maximum bad password attempts.
|
||||
|
||||
### badpasswordattempts
|
||||
|
||||
The `badpasswordattempts` matcher tests the count of bad password attempts for a user.
|
||||
|
||||
its('badpasswordattempts') { should eq 0 }
|
||||
|
||||
where `0` is the count of bad passwords for a user.
|
||||
On Linux based operating systems it relies on `lastb` and for Windows it uses information stored for the user object.
|
||||
These settings will be resetted to `0` depending on your operating system configuration.
|
|
@ -31,7 +31,7 @@ A `users` resource block declares a user name, and then one (or more) matchers:
|
|||
|
||||
where
|
||||
|
||||
* `gid`, `group`, `groups`, `home`, `maxdays`, `mindays`, `shell`, `uid`, and `warndays` are valid matchers for this resource
|
||||
* `gid`, `group`, `groups`, `home`, `maxdays`, `mindays`, `shell`, `uid`, `warndays`, `passwordage`, `maxbadpasswords` and `badpasswordattempts` are valid matchers for this resource
|
||||
* `where(uid: 0).entries` represents a filter that runs the test only against matching users
|
||||
|
||||
For example:
|
||||
|
@ -149,3 +149,29 @@ The `warndays` matcher tests the number of days a user is warned before a passwo
|
|||
its('warndays') { should eq 5 }
|
||||
|
||||
where `5` represents the number of days a user is warned.
|
||||
|
||||
### passwordage
|
||||
|
||||
The `passwordage` matcher tests the number of days a user changed its password:
|
||||
|
||||
its('passwordage') { should_be <= 365 }
|
||||
|
||||
where `365` represents the number of days since the last password change.
|
||||
|
||||
### maxbadpasswords
|
||||
|
||||
The `maxbadpasswords` matcher tests the count of max badpassword settings for a specific user.
|
||||
|
||||
its('maxbadpasswords') { should eq 7 }
|
||||
|
||||
where `7` is the count of maximum bad password attempts.
|
||||
|
||||
### badpasswordattempts
|
||||
|
||||
The `badpasswordattempts` matcher tests the count of bad password attempts for a user.
|
||||
|
||||
its('badpasswordattempts') { should eq 0 }
|
||||
|
||||
where `0` is the count of bad passwords for a user.
|
||||
On Linux based operating systems it relies on `lastb` and for Windows it uses information stored for the user object.
|
||||
These settings will be resetted to `0` depending on your operating system configuration.
|
|
@ -46,11 +46,11 @@ $ inspec shell -t docker://container_id # Login to a Docker container.
|
|||
## Resource Packs
|
||||
|
||||
Use resource packs to share custom resources with other Chef InSpec users.
|
||||
A resource pack is an Chef InSpec profile that contains only custom resources and no other controls or tests.
|
||||
A resource pack is a Chef InSpec profile that contains only custom resources and no other controls or tests.
|
||||
|
||||
For example, the profile in [`examples/profile`](https://github.com/chef/inspec/tree/master/examples/profile)in the Chef InSpec git repo defines a [`gordon_config` resource](https://github.com/chef/inspec/blob/master/examples/profile/controls/gordon.rb). To use these resources within the Chef InSpec shell, you will need to download and specify them as a dependency.
|
||||
For example, the profile in [`examples/profile`](https://github.com/chef/inspec/tree/master/examples/profile)in the Chef InSpec git repo defines a [`example_config` resource](https://github.com/chef/inspec/blob/master/examples/profile/controls/example.rb). To use these resources within the Chef InSpec shell, you will need to download and specify them as a dependency.
|
||||
|
||||
Once you have local access to the profile, you can use the `gordon_config` custom resource provided in the `examples/profile` GitHub repo in your local environment :
|
||||
Once you have local access to the profile, you can use the `example_config` custom resource provided in the `examples/profile` GitHub repo in your local environment :
|
||||
|
||||
```bash
|
||||
inspec shell --depends examples/profile
|
||||
|
@ -59,7 +59,7 @@ inspec shell --depends examples/profile
|
|||
Once inside the shell your resource will be available:
|
||||
|
||||
```ruby
|
||||
inspec> gordon_config
|
||||
inspec> example_config
|
||||
```
|
||||
|
||||
## Using Ruby in Chef InSpec shell
|
||||
|
|
50
docs/waivers.md
Normal file
50
docs/waivers.md
Normal file
|
@ -0,0 +1,50 @@
|
|||
# Waivers (beta)
|
||||
|
||||
Waivers is a mechanism to mark controls as "waived" for various reasons, and to control the running and/or reporting of those controls.
|
||||
It uses a YAML input file that identifies:
|
||||
|
||||
1. which controls are waived
|
||||
2. a description of why it is waived
|
||||
3. (optionally) whether they should be skipped from running
|
||||
4. (optionally) an expiration date for the waiver
|
||||
|
||||
NOTE: This mechanism is currently in beta and is intended to be ingested and maintained by Chef Automate UI.
|
||||
|
||||
## Usage
|
||||
|
||||
To use waivers, you must have a correctly formatted input file and
|
||||
invoke `inspec exec` with `--waiver-file [path]`.
|
||||
|
||||
```
|
||||
% inspec exec --waiver-file waivers.yaml path/to/profile
|
||||
```
|
||||
|
||||
## File Format
|
||||
|
||||
Waiver files are [input files](https://www.inspec.io/docs/reference/inputs/) with a specific format:
|
||||
|
||||
```yaml
|
||||
control_id:
|
||||
expiration_date: YYYY-MM-DD
|
||||
run: false
|
||||
justification: "reason for waiving this control"
|
||||
```
|
||||
|
||||
+ `expiration_date` is optional. Absence means the waiver is permanent.
|
||||
+ `run` is optional. If present and true, the control will run and be
|
||||
reported, but failures in it won't make the overall run fail. If absent or false, the control will not be run. You may use any of yes, no, true or false.
|
||||
+ `justification` can be any text you want and might include a reason
|
||||
as well as who signed off on the waiver.
|
||||
|
||||
### Examples:
|
||||
|
||||
```yaml
|
||||
waiver_control_1_2_3:
|
||||
expiration_date: 2019-10-15
|
||||
justification: Not needed until Q3. @secteam
|
||||
|
||||
xccdf_org.cisecurity.benchmarks_rule_1.1.1.4_Ensure_mounting_of_hfs_filesystems_is_disabled:
|
||||
expiration_date: 2020-03-01
|
||||
justification: "This might be a bug in the test. @qateam"
|
||||
run: false
|
||||
```
|
|
@ -1,5 +1,4 @@
|
|||
describe gordon do
|
||||
its('crime_rate') { should be < 5 }
|
||||
describe example do
|
||||
its('crime_rate') { should be < 2 }
|
||||
it { should have_a_fabulous_mustache }
|
||||
end
|
||||
|
||||
|
|
|
@ -1,21 +1,17 @@
|
|||
class Gordon < Inspec.resource(1)
|
||||
name 'gordon'
|
||||
|
||||
class Example < Inspec.resource(1)
|
||||
name "example"
|
||||
example "
|
||||
describe gordon do
|
||||
describe example do
|
||||
its('crime_rate') { should be < 2 }
|
||||
it { should have_a_fabulous_mustache }
|
||||
end
|
||||
"
|
||||
|
||||
def crime_rate
|
||||
# call out ot another custom resource
|
||||
inspec.batsignal.number_of_sightings
|
||||
1
|
||||
end
|
||||
|
||||
def has_a_fabulous_mustache?
|
||||
# always true
|
||||
true
|
||||
end
|
||||
end
|
||||
|
|
@ -30,8 +30,8 @@ Version: 1.0.0
|
|||
Target: local://
|
||||
|
||||
|
||||
○ gordon-1.0: Verify the version number of Gordon (1 skipped)
|
||||
○ Can't find file "/tmp/gordon/config.yaml"
|
||||
○ example-1.0: Verify the version number of Example (1 skipped)
|
||||
○ Can't find file "/tmp/example/config.yaml"
|
||||
✔ File content should match nil
|
||||
✔ ssh-1: Allow only SSH Protocol 2
|
||||
✔ File /bin/sh should be owned by "root"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
include_controls 'profile' do
|
||||
skip_control 'tmp-1.0'
|
||||
|
||||
control 'gordon-1.0' do
|
||||
control 'example-1.0' do
|
||||
impact 0.0
|
||||
end
|
||||
end
|
||||
|
|
23
examples/profile/controls/example-tmp.rb
Normal file
23
examples/profile/controls/example-tmp.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
# copyright: 2015, Chef Software, Inc.
|
||||
|
||||
title '/tmp profile'
|
||||
|
||||
# you add controls here
|
||||
control "tmp-1.0" do # A unique ID for this control
|
||||
impact 0.7 # The criticality, if this control fails.
|
||||
title "Create /tmp directory" # A human-readable title
|
||||
desc "An optional description..." # Describe why this is needed
|
||||
desc "label", "An optional description with a label" # Pair a part of the description with a label
|
||||
tag data: "temp data" # A tag allows you to associate key information
|
||||
tag "security" # to the test
|
||||
ref "Document A-12", url: 'http://...' # Additional references
|
||||
|
||||
describe file('/tmp') do # The actual test
|
||||
it { should be_directory }
|
||||
end
|
||||
end
|
||||
|
||||
# you can also use plain tests
|
||||
describe file('/tmp') do
|
||||
it { should be_directory }
|
||||
end
|
|
@ -1,23 +1,35 @@
|
|||
# copyright: 2015, Chef Software, Inc.
|
||||
# copyright: 2016, Chef Software, Inc.
|
||||
|
||||
title '/tmp profile'
|
||||
title 'Example Config Checks'
|
||||
|
||||
# you add controls here
|
||||
control "tmp-1.0" do # A unique ID for this control
|
||||
impact 0.7 # The criticality, if this control fails.
|
||||
title "Create /tmp directory" # A human-readable title
|
||||
desc "An optional description..." # Describe why this is needed
|
||||
desc "label", "An optional description with a label" # Pair a part of the description with a label
|
||||
tag data: "temp data" # A tag allows you to associate key information
|
||||
tag "security" # to the test
|
||||
ref "Document A-12", url: 'http://...' # Additional references
|
||||
# To pass the test, create the following file
|
||||
# ```bash
|
||||
# mkdir -p /tmp/example
|
||||
# cat <<EOF > /tmp/example/config.yaml
|
||||
# version: '1.0'
|
||||
# EOF
|
||||
# ```
|
||||
control 'example-1.0' do
|
||||
impact 'critical'
|
||||
title 'Verify the version number of Example'
|
||||
desc 'An optional description...'
|
||||
tag 'example'
|
||||
ref 'Example Requirements 1.0', uri: 'http://...'
|
||||
|
||||
describe file('/tmp') do # The actual test
|
||||
it { should be_directory }
|
||||
# Test using the custom example_config InSpec resource
|
||||
# Find the resource content here: ../libraries/
|
||||
describe example_config do
|
||||
it { should exist }
|
||||
its('version') { should eq('1.0') }
|
||||
its('file_size') { should <= 20 }
|
||||
its('comma_count') { should eq 0 }
|
||||
end
|
||||
|
||||
# Test the version again to showcase variables
|
||||
g = example_config
|
||||
g_path = g.file_path
|
||||
g_version = g.version
|
||||
describe file(g_path) do
|
||||
its('content') { should match g_version }
|
||||
end
|
||||
end
|
||||
|
||||
# you can also use plain tests
|
||||
describe file('/tmp') do
|
||||
it { should be_directory }
|
||||
end
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
# copyright: 2016, Chef Software, Inc.
|
||||
|
||||
title 'Gordon Config Checks'
|
||||
|
||||
# To pass the test, create the following file
|
||||
# ```bash
|
||||
# mkdir -p /tmp/gordon
|
||||
# cat <<EOF > /tmp/gordon/config.yaml
|
||||
# version: '1.0'
|
||||
# EOF
|
||||
# ```
|
||||
control 'gordon-1.0' do
|
||||
impact 'critical'
|
||||
title 'Verify the version number of Gordon'
|
||||
desc 'An optional description...'
|
||||
tag 'gordon'
|
||||
ref 'Gordon Requirements 1.0', uri: 'http://...'
|
||||
|
||||
# Test using the custom gordon_config InSpec resource
|
||||
# Find the resource content here: ../libraries/
|
||||
describe gordon_config do
|
||||
it { should exist }
|
||||
its('version') { should eq('1.0') }
|
||||
its('file_size') { should <= 20 }
|
||||
its('comma_count') { should eq 0 }
|
||||
end
|
||||
|
||||
# Test the version again to showcase variables
|
||||
g = gordon_config
|
||||
g_path = g.file_path
|
||||
g_version = g.version
|
||||
describe file(g_path) do
|
||||
its('content') { should match g_version }
|
||||
end
|
||||
end
|
|
@ -1,18 +1,18 @@
|
|||
require "yaml"
|
||||
|
||||
# Custom resource based on the InSpec resource DSL
|
||||
class GordonConfig < Inspec.resource(1)
|
||||
name "gordon_config"
|
||||
class ExampleConfig < Inspec.resource(1)
|
||||
name "example_config"
|
||||
|
||||
supports platform: "unix"
|
||||
supports platform: "windows"
|
||||
|
||||
desc "
|
||||
Gordon's resource description ...
|
||||
Example's resource description ...
|
||||
"
|
||||
|
||||
example "
|
||||
describe gordon_config do
|
||||
describe example_config do
|
||||
its('version') { should eq('1.0') }
|
||||
its('file_size') { should > 1 }
|
||||
end
|
||||
|
@ -21,7 +21,7 @@ class GordonConfig < Inspec.resource(1)
|
|||
# Load the configuration file on initialization
|
||||
def initialize
|
||||
@params = {}
|
||||
@path = "/tmp/gordon/config.yaml"
|
||||
@path = "/tmp/example/config.yaml"
|
||||
@file = inspec.file(@path)
|
||||
|
||||
unless @file.file?
|
102
habitat/plan.ps1
Normal file
102
habitat/plan.ps1
Normal file
|
@ -0,0 +1,102 @@
|
|||
$pkg_name="inspec"
|
||||
$pkg_origin="chef"
|
||||
$pkg_version=$(Get-Content "$PLAN_CONTEXT/../VERSION")
|
||||
$pkg_revision="1"
|
||||
$pkg_description="InSpec is an open-source testing framework for infrastructure
|
||||
with a human- and machine-readable language for specifying compliance,
|
||||
security and policy requirements."
|
||||
$pkg_upstream_url="https://www.inspec.io/"
|
||||
$pkg_maintainer="The Chef Maintainers <humans@chef.io>"
|
||||
$pkg_license=('Apache-2.0')
|
||||
|
||||
$pkg_deps=@(
|
||||
"core/cacerts"
|
||||
"chef/ruby-plus-devkit"
|
||||
)
|
||||
$pkg_bin_dirs=@("bin"
|
||||
"vendor/bin")
|
||||
$project_root= (Resolve-Path "$PLAN_CONTEXT/../").Path
|
||||
|
||||
function Invoke-Begin {
|
||||
$hab_version = (hab --version)
|
||||
$hab_minor_version = $hab_version.split('.')[1]
|
||||
if ( -not $? -Or $hab_minor_version -lt 85 ) {
|
||||
Write-Warning "I'm being built with $hab_version. I need at least Hab 0.85.0, because I use the -IsPath option for setting/pushing paths in SetupEnvironment."
|
||||
throw "unable to build: required minimum version of Habitat not installed"
|
||||
} else {
|
||||
Write-BuildLine ":habicat: I think I have the version I need to build."
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-SetupEnvironment {
|
||||
Push-RuntimeEnv -IsPath GEM_PATH "$pkg_prefix/vendor"
|
||||
|
||||
Set-RuntimeEnv APPBUNDLER_ALLOW_RVM "true" # prevent appbundler from clearing out the carefully constructed runtime GEM_PATH
|
||||
Set-RuntimeEnv FORCE_FFI_YAJL "ext"
|
||||
Set-RuntimeEnv -IsPath SSL_CERT_FILE "$(Get-HabPackagePath cacerts)/ssl/cert.pem"
|
||||
Set-RuntimeEnv LANG "en_US.UTF-8"
|
||||
Set-RuntimeEnv LC_CTYPE "en_US.UTF-8"
|
||||
}
|
||||
|
||||
function Invoke-Build {
|
||||
try {
|
||||
Push-Location $project_root
|
||||
$env:GEM_HOME = "$HAB_CACHE_SRC_PATH/$pkg_dirname/vendor"
|
||||
|
||||
Write-BuildLine " ** Configuring bundler for this build environment"
|
||||
bundle config --local without integration deploy maintenance
|
||||
bundle config --local jobs 4
|
||||
bundle config --local retry 5
|
||||
bundle config --local silence_root_warning 1
|
||||
|
||||
Write-BuildLine " ** Using bundler to retrieve the Ruby dependencies"
|
||||
bundle install
|
||||
Write-BuildLine " ** Running the inspec project's 'rake install' to install the path-based gems so they look like any other installed gem."
|
||||
bundle exec rake install # this needs to be 'bundle exec'd because a Rakefile makes reference to Bundler
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-Install {
|
||||
Write-BuildLine "** Copy built & cached gems to install directory"
|
||||
Copy-Item -Path "$HAB_CACHE_SRC_PATH/$pkg_dirname/*" -Destination $pkg_prefix -Recurse -Force -Exclude @("gem_make.out", "mkmf.log", "Makefile")
|
||||
|
||||
try {
|
||||
Push-Location $pkg_prefix
|
||||
bundle config --local gemfile $project_root/Gemfile
|
||||
foreach($gem in ("inspec-bin", "inspec")) {
|
||||
Write-BuildLine "** generating binstubs for $gem with precise version pins"
|
||||
Invoke-Expression -Command "appbundler.bat $project_root $pkg_prefix/bin $gem"
|
||||
}
|
||||
Remove-StudioPathFrom -File $pkg_prefix/vendor/gems/inspec-$pkg_version*/Gemfile
|
||||
} finally {
|
||||
Pop-Location
|
||||
# forget about the build bundle config
|
||||
Remove-Item $pkg_prefix/.bundle -Recurse -Force
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-After {
|
||||
# We don't need the cache of downloaded .gem files ...
|
||||
Remove-Item $pkg_prefix/vendor/cache -Recurse -Force
|
||||
# We don't need the gem docs.
|
||||
Remove-Item $pkg_prefix/vendor/doc -Recurse -Force
|
||||
# We don't need to ship the test suites for every gem dependency,
|
||||
# only inspec's for package verification.
|
||||
Get-ChildItem $pkg_prefix/vendor/gems -Filter "spec" -Directory -Recurse -Depth 1 `
|
||||
| Where-Object -FilterScript { $_.FullName -notlike "*inspec*" } `
|
||||
| Remove-Item -Recurse -Force
|
||||
# Remove the byproducts of compiling gems with extensions
|
||||
Get-ChildItem $pkg_prefix/vendor/gems -Include @("gem_make.out", "mkmf.log", "Makefile") -File -Recurse `
|
||||
| Remove-Item -Force
|
||||
}
|
||||
|
||||
function Remove-StudioPathFrom {
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[String]
|
||||
$File
|
||||
)
|
||||
(Get-Content $File) -replace ($env:FS_ROOT -replace "\\","/"),"" | Set-Content $File
|
||||
}
|
|
@ -1,2 +1,7 @@
|
|||
source "https://rubygems.org"
|
||||
gemspec name: "inspec-bin"
|
||||
main_gemspec = File.expand_path("../inspec-bin.gemspec", __FILE__)
|
||||
if File.exist?(main_gemspec)
|
||||
gemspec name: "inspec-bin"
|
||||
else
|
||||
gemspec name: "inspec-core-bin"
|
||||
end
|
||||
|
|
10
inspec-bin/Rakefile
Normal file
10
inspec-bin/Rakefile
Normal file
|
@ -0,0 +1,10 @@
|
|||
Bundler::GemHelper.install_tasks(name: "inspec-bin")
|
||||
|
||||
desc "force install the inspec-bin gem"
|
||||
task "install:force" do
|
||||
sh "gem build -V inspec-bin.gemspec"
|
||||
built_gem_path = Dir["inspec-bin-*.gem"].sort_by { |f| File.mtime(f) }.last
|
||||
FileUtils.mkdir_p("pkg") unless Dir.exist?("pkg")
|
||||
FileUtils.mv(built_gem_path, "pkg")
|
||||
sh "gem install -f pkg/#{built_gem_path}"
|
||||
end
|
|
@ -1,5 +1,5 @@
|
|||
# This file managed by automation - do not edit manually
|
||||
module InspecBin
|
||||
INSPECBIN_ROOT = File.expand_path("../..", __FILE__)
|
||||
VERSION = "4.17.5".freeze
|
||||
VERSION = "4.18.26".freeze
|
||||
end
|
||||
|
|
|
@ -21,11 +21,12 @@ Gem::Specification.new do |spec|
|
|||
|
||||
spec.add_dependency "train-core", "~> 3.0"
|
||||
spec.add_dependency "license-acceptance", ">= 0.2.13", "< 2.0"
|
||||
spec.add_dependency "chef-core", "~> 0.0"
|
||||
spec.add_dependency "thor", "~> 0.20"
|
||||
spec.add_dependency "json-schema", "~> 2.8"
|
||||
spec.add_dependency "method_source", "~> 0.8"
|
||||
spec.add_dependency "rubyzip", "~> 1.1"
|
||||
spec.add_dependency "rspec", "~> 3"
|
||||
spec.add_dependency "rspec", ["~> 3.0", "< 3.9"] # TODO: Loosen - See https://github.com/inspec/inspec/issues/4575
|
||||
spec.add_dependency "rspec-its", "~> 1.2"
|
||||
spec.add_dependency "hashie", "~> 3.4"
|
||||
spec.add_dependency "mixlib-log"
|
||||
|
|
|
@ -31,11 +31,12 @@ Gem::Specification.new do |spec|
|
|||
|
||||
# Implementation dependencies
|
||||
spec.add_dependency "license-acceptance", ">= 0.2.13", "< 2.0"
|
||||
spec.add_dependency "chef-core", "~> 0.0"
|
||||
spec.add_dependency "thor", "~> 0.20"
|
||||
spec.add_dependency "json-schema", "~> 2.8"
|
||||
spec.add_dependency "method_source", "~> 0.8"
|
||||
spec.add_dependency "rubyzip", "~> 1.2", ">= 1.2.2"
|
||||
spec.add_dependency "rspec", "~> 3"
|
||||
spec.add_dependency "rspec", ["~> 3.0", "< 3.9"] # TODO: Loosen - See https://github.com/inspec/inspec/issues/4575
|
||||
spec.add_dependency "rspec-its", "~> 1.2"
|
||||
spec.add_dependency "pry", "~> 0"
|
||||
spec.add_dependency "hashie", "~> 3.4"
|
||||
|
|
|
@ -11,7 +11,7 @@ verifier:
|
|||
|
||||
lifecycle:
|
||||
pre_converge:
|
||||
- local: gem build inspec-core.gemspec --output test/cookbooks/os_prepare/files/inspec-core-local.gem
|
||||
- local: gem build inspec-core.gemspec --output test/kitchen/cookbooks/os_prepare/files/inspec-core-local.gem
|
||||
|
||||
platforms:
|
||||
# The following (private) boxes are shared via VagrantCloud and are only
|
||||
|
|
|
@ -11,7 +11,7 @@ verifier:
|
|||
|
||||
lifecycle:
|
||||
pre_converge:
|
||||
- local: gem build inspec-core.gemspec --output test/cookbooks/os_prepare/files/inspec-core-local.gem
|
||||
- local: gem build inspec-core.gemspec --output test/kitchen/cookbooks/os_prepare/files/inspec-core-local.gem
|
||||
|
||||
platforms:
|
||||
- name: centos-6
|
||||
|
@ -35,6 +35,6 @@ suites:
|
|||
- recipe[os_prepare::find_files]
|
||||
verifier:
|
||||
inspec_tests:
|
||||
- test/integration/find_files
|
||||
- test/kitchen/policies/find_files
|
||||
excludes:
|
||||
- freebsd-11
|
||||
|
|
10
kitchen.yml
10
kitchen.yml
|
@ -9,7 +9,7 @@ transport:
|
|||
|
||||
lifecycle:
|
||||
pre_converge:
|
||||
- local: gem build inspec-core.gemspec --output test/cookbooks/os_prepare/files/inspec-core-local.gem
|
||||
- local: gem build inspec-core.gemspec --output test/kitchen/cookbooks/os_prepare/files/inspec-core-local.gem
|
||||
|
||||
provisioner:
|
||||
name: dokken
|
||||
|
@ -100,13 +100,13 @@ platforms:
|
|||
- RUN /usr/bin/apt-get update -y
|
||||
|
||||
suites:
|
||||
- name: default
|
||||
- name: resources-core
|
||||
run_list:
|
||||
- recipe[os_prepare]
|
||||
- recipe[audit]
|
||||
verifier:
|
||||
inspec_tests:
|
||||
- test/integration/default
|
||||
- test/kitchen/policies/resources-core
|
||||
attributes:
|
||||
audit:
|
||||
attributes:
|
||||
|
@ -122,3 +122,7 @@ suites:
|
|||
osprepare:
|
||||
docker: true
|
||||
application: false
|
||||
|
||||
- name: resources-database
|
||||
- name: resources-unix
|
||||
- name: resources-windows
|
||||
|
|
|
@ -222,16 +222,20 @@ module Inspec
|
|||
|
||||
private
|
||||
|
||||
ALL_OF_OUR_REPORTERS = %w{json json-min json-rspec json-automate junit html yaml documentation progress}.freeze # BUT WHY?!?!
|
||||
|
||||
def suppress_log_output?(opts)
|
||||
return false if opts["reporter"].nil?
|
||||
|
||||
match = %w{json json-min json-rspec json-automate junit html yaml documentation progress} & opts["reporter"].keys
|
||||
match = ALL_OF_OUR_REPORTERS & opts["reporter"].keys
|
||||
|
||||
unless match.empty?
|
||||
match.each do |m|
|
||||
# check to see if we are outputting to stdout
|
||||
return true if opts["reporter"][m]["stdout"] == true
|
||||
end
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ module Inspec # TODO: move this somewhere "better"?
|
|||
autoload :BaseCLI, "inspec/base_cli"
|
||||
autoload :Deprecation, "inspec/utils/deprecation"
|
||||
autoload :Exceptions, "inspec/exceptions"
|
||||
autoload :EnvPrinter, "inspec/env_printer"
|
||||
autoload :Fetcher, "inspec/fetcher"
|
||||
autoload :Formatters, "inspec/formatters"
|
||||
autoload :Globals, "inspec/globals"
|
||||
|
@ -340,7 +341,15 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|||
ui.exit res unless run_type == :ruby_eval
|
||||
|
||||
# No InSpec tests - just print evaluation output.
|
||||
res = (res.respond_to?(:to_json) ? res.to_json : JSON.dump(res)) if o["reporter"]&.keys&.include?("json")
|
||||
reporters = o["reporter"] || {}
|
||||
if reporters.keys.include?("json")
|
||||
res = if res.respond_to?(:to_json)
|
||||
res.to_json
|
||||
else
|
||||
JSON.dump(res)
|
||||
end
|
||||
end
|
||||
|
||||
puts res
|
||||
ui.exit Inspec::UI::EXIT_NORMAL
|
||||
rescue RuntimeError, Train::UserError => e
|
||||
|
|
|
@ -135,6 +135,11 @@ module Inspec
|
|||
Thor::CoreExt::HashWithIndifferentAccess.new(@plugin_cfg[plugin_name] || {})
|
||||
end
|
||||
|
||||
# clear the cached config
|
||||
def self.__reset
|
||||
@cached_config = nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def _utc_merge_transport_options(credentials, transport_name)
|
||||
|
|
|
@ -19,6 +19,8 @@ module Inspec
|
|||
def initialize(path = nil)
|
||||
@path = path || File.join(Inspec.config_dir, "cache")
|
||||
FileUtils.mkdir_p(@path) unless File.directory?(@path)
|
||||
rescue Errno::EACCES
|
||||
# ignore
|
||||
end
|
||||
|
||||
def prefered_entry_for(key)
|
||||
|
|
|
@ -17,6 +17,10 @@ module Inspec
|
|||
@action.call("describe.one", @checks, nil)
|
||||
end
|
||||
|
||||
def method_missing(method_name, *arguments)
|
||||
Inspec::DSL.method_missing_resource(inspec, method_name, *arguments)
|
||||
end
|
||||
|
||||
def describe(*args, &block)
|
||||
@checks.push(["describe", args, block])
|
||||
end
|
|
@ -34,6 +34,8 @@ module Inspec::DSL
|
|||
# resource.
|
||||
|
||||
def self.method_missing_resource(backend, id, *arguments)
|
||||
return unless backend
|
||||
|
||||
begin
|
||||
require "inspec/resources/#{id}"
|
||||
rescue LoadError
|
||||
|
|
|
@ -171,7 +171,7 @@ module Inspec
|
|||
path = Pathname.new(name).relative_path_from(here).to_s
|
||||
|
||||
@contents[path] = begin # not ||= in a tarball, last one wins
|
||||
res = entry.read
|
||||
res = entry.read || ""
|
||||
try = res.dup
|
||||
try.force_encoding Encoding::UTF_8
|
||||
res = try if try.valid_encoding?
|
||||
|
|
|
@ -259,6 +259,11 @@ module Inspec::Formatters
|
|||
example.delete(:id)
|
||||
example.delete(:profile_id)
|
||||
control[:results].push(example)
|
||||
|
||||
# Waiver data, if available, is internally stored on a per-result
|
||||
# (that is, per-describe-block) basis, because that is the only granularity
|
||||
# available to us in the RSpec report data structure which we use as a vehicle.
|
||||
control[:waiver_data] ||= example[:waiver_data] || {}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -318,6 +318,17 @@ module Inspec
|
|||
!current_value.is_a? NO_VALUE_SET
|
||||
end
|
||||
|
||||
def to_hash
|
||||
as_hash = { name: name, options: {} }
|
||||
%i{description title identifier type required value}.each do |field|
|
||||
val = send(field)
|
||||
next if val.nil?
|
||||
|
||||
as_hash[:options][field] = val
|
||||
end
|
||||
as_hash
|
||||
end
|
||||
|
||||
#--------------------------------------------------------------------------#
|
||||
# Value Type Coercion
|
||||
#--------------------------------------------------------------------------#
|
||||
|
|
|
@ -16,7 +16,7 @@ module Inspec
|
|||
|
||||
module ResourceDSL
|
||||
def name(name = nil)
|
||||
return if name.nil?
|
||||
return @name if name.nil?
|
||||
|
||||
@name = name
|
||||
__register(name, self)
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
require "inspec/log"
|
||||
require "inspec/version"
|
||||
require "inspec/plugin/v2/config_file"
|
||||
require "inspec/plugin/v2/filter"
|
||||
|
||||
# Add the current directory of the process to the load path
|
||||
$LOAD_PATH.unshift(".") unless $LOAD_PATH.include?(".")
|
||||
# Add the InSpec source root directory to the load path
|
||||
folder = File.expand_path(File.join("..", "..", "..", ".."), __dir__)
|
||||
$LOAD_PATH.unshift(folder) unless $LOAD_PATH.include?("folder")
|
||||
|
||||
module Inspec::Plugin::V2
|
||||
class Loader
|
||||
attr_reader :conf_file, :registry, :options
|
||||
|
@ -274,9 +269,22 @@ module Inspec::Plugin::V2
|
|||
end
|
||||
end
|
||||
|
||||
def find_inspec_gemspec(name, ver)
|
||||
Gem::Specification.find_by_name(name, ver)
|
||||
rescue Gem::MissingSpecError
|
||||
nil
|
||||
end
|
||||
|
||||
def detect_system_plugins
|
||||
# Find the gemspec for inspec
|
||||
inspec_gemspec = Gem::Specification.find_by_name("inspec", "=#{Inspec::VERSION}")
|
||||
inspec_gemspec =
|
||||
find_inspec_gemspec("inspec", "=#{Inspec::VERSION}") ||
|
||||
find_inspec_gemspec("inspec-core", "=#{Inspec::VERSION}")
|
||||
|
||||
unless inspec_gemspec
|
||||
Inspec::Log.warn "inspec gem not found, skipping detecting of system plugins"
|
||||
return
|
||||
end
|
||||
|
||||
# Make a RequestSet that represents the dependencies of inspec
|
||||
inspec_deps_request_set = Gem::RequestSet.new(*inspec_gemspec.dependencies)
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
# copyright: 2016, Chef Software Inc.
|
||||
|
||||
class Struct
|
||||
unless instance_methods.include? :to_h
|
||||
def to_h
|
||||
Hash[each_pair.to_a]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -332,6 +332,7 @@ module Inspec
|
|||
# convert legacy os-* supports to their platform counterpart
|
||||
if res[:supports] && !res[:supports].empty?
|
||||
res[:supports].each do |support|
|
||||
# TODO: deprecate
|
||||
support[:"platform-family"] = support.delete(:"os-family") if support.key?(:"os-family")
|
||||
support[:"platform-name"] = support.delete(:"os-name") if support.key?(:"os-name")
|
||||
end
|
||||
|
|
|
@ -40,7 +40,6 @@ module Inspec::Reporters
|
|||
message: r[:message],
|
||||
exception: r[:exception],
|
||||
backtrace: r[:backtrace],
|
||||
waiver_data: r[:waiver_data],
|
||||
}.reject { |_k, v| v.nil? }
|
||||
}
|
||||
end
|
||||
|
@ -96,6 +95,7 @@ module Inspec::Reporters
|
|||
line: c[:source_location][:line],
|
||||
ref: c[:source_location][:ref],
|
||||
},
|
||||
waiver_data: c[:waiver_data] || {},
|
||||
results: profile_results(c),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,10 +10,12 @@ module Inspec
|
|||
@default_registry ||= {}
|
||||
end
|
||||
|
||||
# TODO: these are keyed off of strings
|
||||
def self.registry
|
||||
@registry ||= default_registry
|
||||
end
|
||||
|
||||
# TODO: these are keyed off of symbols
|
||||
def self.supports
|
||||
@supports ||= {}
|
||||
end
|
||||
|
@ -22,6 +24,29 @@ module Inspec
|
|||
default_registry.dup
|
||||
end
|
||||
|
||||
def self.backfill_supports!
|
||||
reg = registry.keys.map(&:to_sym).sort
|
||||
sup = supports.keys.map(&:to_sym).sort
|
||||
|
||||
missings = reg - sup
|
||||
|
||||
supports[:platform] = [{ platform: "os" }] # patch the circular dep
|
||||
|
||||
missings.each do |missing|
|
||||
klass = registry[missing.to_s].superclass
|
||||
sklas = klass.superclass.name&.to_sym # might be resource = no name
|
||||
|
||||
klass = klass.name.to_sym
|
||||
|
||||
case
|
||||
when klass != missing # an alias
|
||||
supports[missing] = supports[klass]
|
||||
when sklas
|
||||
supports[klass] = supports[sklas]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Creates the inner DSL which includes all resources for
|
||||
# creating tests. It is always connected to one target,
|
||||
# which is specified via the backend argument.
|
||||
|
|
|
@ -87,12 +87,14 @@ module Inspec::Resources
|
|||
active = raw_line == line
|
||||
|
||||
# formats:
|
||||
# deb "http://archive.ubuntu.com/ubuntu/" wily main restricted ...
|
||||
# deb http://archive.ubuntu.com/ubuntu/ wily main restricted ...
|
||||
# deb [trusted=yes] http://archive.ubuntu.com/ubuntu/ wily main restricted ...
|
||||
|
||||
words = line.split
|
||||
words.delete 1 if words[1] && words[1].start_with?("[")
|
||||
type, url, distro, *components = words
|
||||
url = url.delete('"') if url
|
||||
|
||||
next if components.empty?
|
||||
next unless URI::HTTP === URI.parse(url)
|
||||
|
|
2
lib/inspec/resources/bsd_service.rb
Normal file
2
lib/inspec/resources/bsd_service.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/service"
|
2
lib/inspec/resources/etc_hosts_allow.rb
Normal file
2
lib/inspec/resources/etc_hosts_allow.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/etc_hosts_allow_deny"
|
|
@ -33,6 +33,10 @@ module Inspec::Resources
|
|||
|
||||
filter.install_filter_methods_on_resource(self, :params)
|
||||
|
||||
def to_s
|
||||
"hosts.allow Configuration"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def read_content
|
||||
|
|
2
lib/inspec/resources/etc_hosts_deny.rb
Normal file
2
lib/inspec/resources/etc_hosts_deny.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/etc_hosts_allow_deny"
|
|
@ -95,7 +95,7 @@ module Inspec::Resources
|
|||
|
||||
class LinuxFileSystemResource < FsManagement
|
||||
def info(partition)
|
||||
cmd = inspec.command("df #{partition} -T")
|
||||
cmd = inspec.command("df #{partition} -PT")
|
||||
if cmd.stdout.nil? || cmd.stdout.empty? || cmd.exit_status != 0
|
||||
raise Inspec::Exceptions::ResourceFailed,
|
||||
"Unable to get available space for partition #{partition}"
|
||||
|
|
2
lib/inspec/resources/group.rb
Normal file
2
lib/inspec/resources/group.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/groups"
|
|
@ -22,10 +22,6 @@ module Inspec::Resources
|
|||
def initialize(pool_name)
|
||||
@pool_name = pool_name
|
||||
@pool_path = "IIS:\\AppPools\\#{@pool_name}"
|
||||
@cache = nil
|
||||
|
||||
# verify that this resource is only supported on Windows
|
||||
return skip_resource "The `iis_app_pool` resource is not supported on your OS." unless inspec.os.windows?
|
||||
end
|
||||
|
||||
def pool_name
|
||||
|
@ -77,7 +73,7 @@ module Inspec::Resources
|
|||
end
|
||||
|
||||
def exists?
|
||||
!iis_app_pool[:pool_name].empty?
|
||||
!!iis_app_pool[:pool_name]
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
@ -87,45 +83,45 @@ module Inspec::Resources
|
|||
private
|
||||
|
||||
def iis_app_pool
|
||||
return @cache unless @cache.nil?
|
||||
@iis_app_pool ||= begin
|
||||
# We use `-Compress` here to avoid a bug in PowerShell
|
||||
# It does not affect validity of the output, only the representation
|
||||
# See: https://github.com/inspec/inspec/pull/3842
|
||||
script = <<~EOH
|
||||
Import-Module WebAdministration
|
||||
If (Test-Path '#{@pool_path}') {
|
||||
Get-Item '#{@pool_path}' | Select-Object * | ConvertTo-Json -Compress
|
||||
} Else {
|
||||
Write-Host '{}'
|
||||
}
|
||||
EOH
|
||||
cmd = inspec.powershell(script)
|
||||
|
||||
# We use `-Compress` here to avoid a bug in PowerShell
|
||||
# It does not affect validity of the output, only the representation
|
||||
# See: https://github.com/inspec/inspec/pull/3842
|
||||
script = <<~EOH
|
||||
Import-Module WebAdministration
|
||||
If (Test-Path '#{@pool_path}') {
|
||||
Get-Item '#{@pool_path}' | Select-Object * | ConvertTo-Json -Compress
|
||||
} Else {
|
||||
Write-Host '{}'
|
||||
begin
|
||||
pool = JSON.parse(cmd.stdout)
|
||||
rescue JSON::ParserError => _e
|
||||
raise Inspec::Exceptions::ResourceFailed, "Unable to parse app pool JSON"
|
||||
end
|
||||
|
||||
process_model = pool.fetch("processModel", {})
|
||||
idle_timeout = process_model.fetch("idleTimeout", {})
|
||||
|
||||
# map our values to a hash table
|
||||
@cache = {
|
||||
pool_name: pool["name"],
|
||||
version: pool["managedRuntimeVersion"],
|
||||
e32b: pool["enable32BitAppOnWin64"],
|
||||
mode: pool["managedPipelineMode"],
|
||||
processes: process_model["maxProcesses"],
|
||||
timeout: "#{idle_timeout["Hours"]}:#{idle_timeout["Minutes"]}:#{idle_timeout["Seconds"]}",
|
||||
timeout_days: idle_timeout["Days"],
|
||||
timeout_hours: idle_timeout["Hours"],
|
||||
timeout_minutes: idle_timeout["Minutes"],
|
||||
timeout_seconds: idle_timeout["Seconds"],
|
||||
user_identity_type: process_model["identityType"],
|
||||
username: process_model["userName"],
|
||||
}
|
||||
EOH
|
||||
cmd = inspec.powershell(script)
|
||||
|
||||
begin
|
||||
pool = JSON.parse(cmd.stdout)
|
||||
rescue JSON::ParserError => _e
|
||||
raise Inspec::Exceptions::ResourceFailed, "Unable to parse app pool JSON"
|
||||
end
|
||||
|
||||
process_model = pool.fetch("processModel", {})
|
||||
idle_timeout = process_model.fetch("idleTimeout", {})
|
||||
|
||||
# map our values to a hash table
|
||||
@cache = {
|
||||
pool_name: pool["name"],
|
||||
version: pool["managedRuntimeVersion"],
|
||||
e32b: pool["enable32BitAppOnWin64"],
|
||||
mode: pool["managedPipelineMode"],
|
||||
processes: process_model["maxProcesses"],
|
||||
timeout: "#{idle_timeout["Hours"]}:#{idle_timeout["Minutes"]}:#{idle_timeout["Seconds"]}",
|
||||
timeout_days: idle_timeout["Days"],
|
||||
timeout_hours: idle_timeout["Hours"],
|
||||
timeout_minutes: idle_timeout["Minutes"],
|
||||
timeout_seconds: idle_timeout["Seconds"],
|
||||
user_identity_type: process_model["identityType"],
|
||||
username: process_model["userName"],
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
2
lib/inspec/resources/iis_website.rb
Normal file
2
lib/inspec/resources/iis_website.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/iis_website.rb"
|
|
@ -17,38 +17,34 @@ module Inspec::Resources
|
|||
its('ipv6_cidrs') { should include '::1/128' }
|
||||
end
|
||||
EXAMPLE
|
||||
|
||||
def initialize(iface)
|
||||
@iface = iface
|
||||
|
||||
@interface_provider = nil
|
||||
if inspec.os.linux?
|
||||
@interface_provider = LinuxInterface.new(inspec)
|
||||
elsif inspec.os.windows?
|
||||
@interface_provider = WindowsInterface.new(inspec)
|
||||
else
|
||||
return skip_resource "The `interface` resource is not supported on your OS yet."
|
||||
end
|
||||
end
|
||||
|
||||
def exists?
|
||||
!interface_info.nil? && !interface_info[:name].nil?
|
||||
!!(interface_info && interface_info[:name])
|
||||
end
|
||||
|
||||
def up?
|
||||
interface_info.nil? ? false : interface_info[:up]
|
||||
!!(interface_info && interface_info[:up])
|
||||
end
|
||||
|
||||
def name
|
||||
interface_info[:name]
|
||||
end
|
||||
|
||||
# returns link speed in Mbits/sec
|
||||
def speed
|
||||
interface_info.nil? ? nil : interface_info[:speed]
|
||||
interface_info && interface_info[:speed]
|
||||
end
|
||||
|
||||
def ipv4_address?
|
||||
!ipv4_addresses.nil? && !ipv4_addresses.empty?
|
||||
ipv4_addresses && !ipv4_addresses.empty?
|
||||
end
|
||||
|
||||
def ipv6_address?
|
||||
!ipv6_addresses.nil? && !ipv6_addresses.empty?
|
||||
ipv6_addresses && !ipv6_addresses.empty?
|
||||
end
|
||||
|
||||
def ipv4_addresses
|
||||
|
@ -72,11 +68,11 @@ module Inspec::Resources
|
|||
end
|
||||
|
||||
def ipv4_cidrs
|
||||
interface_info.nil? ? [] : interface_info[:ipv4_addresses]
|
||||
interface_info && Array(interface_info[:ipv4_addresses])
|
||||
end
|
||||
|
||||
def ipv6_cidrs
|
||||
interface_info.nil? ? [] : interface_info[:ipv6_addresses]
|
||||
interface_info && Array(interface_info[:ipv6_addresses])
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
@ -86,9 +82,11 @@ module Inspec::Resources
|
|||
private
|
||||
|
||||
def interface_info
|
||||
return @cache if defined?(@cache)
|
||||
|
||||
@cache = @interface_provider.interface_info(@iface) unless @interface_provider.nil?
|
||||
@cache ||= begin
|
||||
provider = LinuxInterface.new(inspec) if inspec.os.linux?
|
||||
provider = WindowsInterface.new(inspec) if inspec.os.windows?
|
||||
Hash(provider && provider.interface_info(@iface))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ require "inspec/utils/file_reader"
|
|||
module Inspec::Resources
|
||||
class JsonConfig < Inspec.resource(1)
|
||||
name "json"
|
||||
supports platform: "os"
|
||||
desc "Use the json InSpec audit resource to test data in a JSON file."
|
||||
example <<~EXAMPLE
|
||||
describe json('policyfile.lock.json') do
|
||||
|
|
2
lib/inspec/resources/launchd_service.rb
Normal file
2
lib/inspec/resources/launchd_service.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/service"
|
2
lib/inspec/resources/linux_kernel_parameter.rb
Normal file
2
lib/inspec/resources/linux_kernel_parameter.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/kernel_parameter"
|
|
@ -11,6 +11,7 @@ module Inspec::Resources
|
|||
# @see https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-connect-and-query-sqlcmd
|
||||
class MssqlSession < Inspec.resource(1)
|
||||
name "mssql_session"
|
||||
supports platform: "windows"
|
||||
desc "Use the mssql_session InSpec audit resource to test SQL commands run against a MS Sql Server database."
|
||||
example <<~EXAMPLE
|
||||
# Using SQL authentication
|
||||
|
|
9
lib/inspec/resources/noop.rb
Normal file
9
lib/inspec/resources/noop.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
module Inspec::Resources
|
||||
class Noop < Inspec.resource(1)
|
||||
name "noop"
|
||||
|
||||
def to_s
|
||||
"No-op"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,8 +1,8 @@
|
|||
require "inspec/resources/command"
|
||||
require "hashie/mash"
|
||||
require "inspec/utils/database_helpers"
|
||||
require "htmlentities"
|
||||
require "rexml/document"
|
||||
require "hashie/mash"
|
||||
require "csv"
|
||||
|
||||
module Inspec::Resources
|
||||
|
@ -21,8 +21,9 @@ module Inspec::Resources
|
|||
end
|
||||
EXAMPLE
|
||||
|
||||
attr_reader :user, :password, :host, :service, :as_os_user, :as_db_role
|
||||
# rubocop:disable Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity
|
||||
attr_reader :bin, :db_role, :host, :password, :port, :service,
|
||||
:su_user, :user
|
||||
|
||||
def initialize(opts = {})
|
||||
@user = opts[:user]
|
||||
@password = opts[:password] || opts[:pass]
|
||||
|
@ -30,60 +31,35 @@ module Inspec::Resources
|
|||
Inspec.deprecate(:oracledb_session_pass_option, "The oracledb_session `pass` option is deprecated. Please use `password`.")
|
||||
end
|
||||
|
||||
@bin = "sqlplus"
|
||||
@host = opts[:host] || "localhost"
|
||||
@port = opts[:port] || "1521"
|
||||
@service = opts[:service]
|
||||
|
||||
# connection as sysdba stuff
|
||||
return skip_resource "Option 'as_os_user' not available in Windows" if inspec.os.windows? && opts[:as_os_user]
|
||||
|
||||
@su_user = opts[:as_os_user]
|
||||
@db_role = opts[:as_db_role]
|
||||
|
||||
# we prefer sqlci although it is way slower than sqlplus, but it understands csv properly
|
||||
@sqlcl_bin = "sql" unless opts.key?(:sqlplus_bin) # don't use it if user specified sqlplus_bin option
|
||||
@sqlcl_bin = opts[:sqlcl_bin] || nil
|
||||
@sqlplus_bin = opts[:sqlplus_bin] || "sqlplus"
|
||||
|
||||
return fail_resource "Can't run Oracle checks without authentication" if @su_user.nil? && (@user.nil? || @password.nil?)
|
||||
return fail_resource "You must provide a service name for the session" if @service.nil?
|
||||
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
|
||||
end
|
||||
|
||||
def query(q)
|
||||
escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '\\"')
|
||||
# escape tables with $
|
||||
escaped_query = escaped_query.gsub("$", '\\$')
|
||||
|
||||
p = nil
|
||||
# use sqlplus if sqlcl is not available
|
||||
def query(sql)
|
||||
if @sqlcl_bin && inspec.command(@sqlcl_bin).exist?
|
||||
bin = @sqlcl_bin
|
||||
opts = "set sqlformat csv\nSET FEEDBACK OFF"
|
||||
p = :parse_csv_result
|
||||
@bin = @sqlcl_bin
|
||||
format_options = "set sqlformat csv\nSET FEEDBACK OFF"
|
||||
parser = :parse_csv_result
|
||||
else
|
||||
bin = @sqlplus_bin
|
||||
opts = "SET MARKUP HTML ON\nSET PAGESIZE 32000\nSET FEEDBACK OFF"
|
||||
p = :parse_html_result
|
||||
@bin = "#{@sqlplus_bin} -S"
|
||||
format_options = "SET MARKUP HTML ON\nSET PAGESIZE 32000\nSET FEEDBACK OFF"
|
||||
parser = :parse_html_result
|
||||
end
|
||||
|
||||
query = verify_query(escaped_query)
|
||||
query += ";" unless query.end_with?(";")
|
||||
if @db_role.nil?
|
||||
command = %{#{bin} "#{@user}"/"#{@password}"@#{@host}:#{@port}/#{@service} <<EOC\n#{opts}\n#{query}\nEXIT\nEOC}
|
||||
elsif @su_user.nil?
|
||||
command = %{#{bin} "#{@user}"/"#{@password}"@#{@host}:#{@port}/#{@service} as #{@db_role} <<EOC\n#{opts}\n#{query}\nEXIT\nEOC}
|
||||
else
|
||||
command = %{su - #{@su_user} -c "env ORACLE_SID=#{@service} #{bin} / as #{@db_role} <<EOC\n#{opts}\n#{query}\nEXIT\nEOC"}
|
||||
end
|
||||
cmd = inspec.command(command)
|
||||
command = command_builder(format_options, sql)
|
||||
inspec_cmd = inspec.command(command)
|
||||
|
||||
out = cmd.stdout + "\n" + cmd.stderr
|
||||
if out.downcase =~ /^error/
|
||||
# TODO: we need to throw an exception here
|
||||
# change once https://github.com/chef/inspec/issues/1205 is in
|
||||
warn "Could not execute the sql query #{out}"
|
||||
DatabaseHelper::SQLQueryResult.new(cmd, Hashie::Mash.new({}))
|
||||
end
|
||||
DatabaseHelper::SQLQueryResult.new(cmd, send(p, cmd.stdout))
|
||||
DatabaseHelper::SQLQueryResult.new(inspec_cmd, send(parser,
|
||||
inspec_cmd.stdout))
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
@ -92,9 +68,30 @@ module Inspec::Resources
|
|||
|
||||
private
|
||||
|
||||
# 3 commands
|
||||
# regular user password
|
||||
# using a db_role
|
||||
# su, using a db_role
|
||||
def command_builder(format_options, query)
|
||||
verified_query = verify_query(query)
|
||||
sql_prefix, sql_postfix = "", ""
|
||||
if inspec.os.windows?
|
||||
sql_prefix = %{@'\n#{format_options}\n#{verified_query}\nEXIT\n'@ | }
|
||||
else
|
||||
sql_postfix = %{ <<'EOC'\n#{format_options}\n#{verified_query}\nEXIT\nEOC}
|
||||
end
|
||||
|
||||
if @db_role.nil?
|
||||
%{#{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}}
|
||||
else
|
||||
%{su - #{@su_user} -c "env ORACLE_SID=#{@service} #{bin} / as #{@db_role}#{sql_postfix}}
|
||||
end
|
||||
end
|
||||
|
||||
def verify_query(query)
|
||||
# ensure we have a ; at the end
|
||||
query + ";" unless query.strip.end_with?(";")
|
||||
query += ";" unless query.strip.end_with?(";")
|
||||
query
|
||||
end
|
||||
|
||||
|
@ -115,7 +112,7 @@ module Inspec::Resources
|
|||
results
|
||||
end
|
||||
|
||||
def parse_html_result(stdout) # rubocop:disable Metrics/AbcSize
|
||||
def parse_html_result(stdout)
|
||||
result = stdout
|
||||
# make oracle html valid html by removing the p tag, it does not include a closing tag
|
||||
result = result.gsub("<p>", "").gsub("</p>", "").gsub("<br>", "")
|
||||
|
|
2
lib/inspec/resources/parse_config_file.rb
Normal file
2
lib/inspec/resources/parse_config_file.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/parse_config"
|
2
lib/inspec/resources/ppa.rb
Normal file
2
lib/inspec/resources/ppa.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/apt.rb"
|
2
lib/inspec/resources/rabbitmq_conf.rb
Normal file
2
lib/inspec/resources/rabbitmq_conf.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/rabbitmq_config.rb"
|
2
lib/inspec/resources/runit_service.rb
Normal file
2
lib/inspec/resources/runit_service.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/service"
|
2
lib/inspec/resources/sshd_config.rb
Normal file
2
lib/inspec/resources/sshd_config.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/ssh_config.rb"
|
2
lib/inspec/resources/systemd_service.rb
Normal file
2
lib/inspec/resources/systemd_service.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/service"
|
2
lib/inspec/resources/sysv_service.rb
Normal file
2
lib/inspec/resources/sysv_service.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/service"
|
2
lib/inspec/resources/upstart_service.rb
Normal file
2
lib/inspec/resources/upstart_service.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/service"
|
|
@ -3,6 +3,7 @@ require "inspec/utils/convert"
|
|||
require "inspec/utils/filter"
|
||||
require "inspec/utils/simpleconfig"
|
||||
require "inspec/resources/powershell"
|
||||
require "date"
|
||||
|
||||
module Inspec::Resources
|
||||
# This file contains two resources, the `user` and `users` resource.
|
||||
|
@ -116,6 +117,24 @@ module Inspec::Resources
|
|||
# its('mindays') { should eq 0 }
|
||||
# its('maxdays') { should eq 99 }
|
||||
# its('warndays') { should eq 5 }
|
||||
# its('passwordage') { should be >= 0 }
|
||||
# its('maxbadpasswords') { should eq nil } // not yet supported on linux
|
||||
# its('badpasswordattempts') { should eq 0 }
|
||||
# end
|
||||
# describe user('Administrator') do
|
||||
# it { should exist }
|
||||
# its('uid') { should eq "S-1-5-21-1759981009-4135989804-1844563890-500" }
|
||||
# its('gid') { should eq nil } // not supported on Windows
|
||||
# its('group') { should eq nil } // not supported on Windows
|
||||
# its('groups') { should eq ['Administrators', 'Users']}
|
||||
# its('home') { should eq '' }
|
||||
# its('shell') { should eq nil } // not supported on Windows
|
||||
# its('mindays') { should eq 0 }
|
||||
# its('maxdays') { should eq 42 }
|
||||
# its('warndays') { should eq nil }
|
||||
# its('passwordage') { should eq 355 }
|
||||
# its('maxbadpasswords') { should eq 0 }
|
||||
# its('badpasswordattempts') { should eq 0 }
|
||||
# end
|
||||
#
|
||||
# The following Serverspec matchers are deprecated in favor for direct value access
|
||||
|
@ -196,6 +215,14 @@ module Inspec::Resources
|
|||
meta_info[:shell] unless meta_info.nil?
|
||||
end
|
||||
|
||||
def domain
|
||||
meta_info[:domain] unless meta_info.nil?
|
||||
end
|
||||
|
||||
def userflags
|
||||
meta_info[:userflags] unless meta_info.nil?
|
||||
end
|
||||
|
||||
# returns the minimum days between password changes
|
||||
def mindays
|
||||
credentials[:mindays] unless credentials.nil?
|
||||
|
@ -211,6 +238,18 @@ module Inspec::Resources
|
|||
credentials[:warndays] unless credentials.nil?
|
||||
end
|
||||
|
||||
def badpasswordattempts
|
||||
credentials[:badpasswordattempts] unless credentials.nil?
|
||||
end
|
||||
|
||||
def maxbadpasswords
|
||||
credentials[:maxbadpasswords] unless credentials.nil?
|
||||
end
|
||||
|
||||
def passwordage
|
||||
credentials[:passwordage] unless credentials.nil?
|
||||
end
|
||||
|
||||
# implement 'mindays' method to be compatible with serverspec
|
||||
def minimum_days_between_password_change
|
||||
Inspec.deprecate(:resource_user_serverspec_compat, "The user resource `minimum_days_between_password_change` property is deprecated. Please use `mindays`.")
|
||||
|
@ -425,10 +464,18 @@ module Inspec::Resources
|
|||
multiple_values: false
|
||||
).params
|
||||
|
||||
last_change = params["Last password change"]
|
||||
dparse = Date.parse "#{last_change}" rescue nil
|
||||
dayslastset = (Date.today - dparse).to_i if dparse
|
||||
cmd = inspec.command("lastb -w -a | grep #{username} | wc -l")
|
||||
badpasswordattempts = convert_to_i(cmd.stdout.chomp) if cmd.exit_status == 0
|
||||
|
||||
{
|
||||
mindays: convert_to_i(params["Minimum number of days between password change"]),
|
||||
maxdays: convert_to_i(params["Maximum number of days between password change"]),
|
||||
warndays: convert_to_i(params["Number of days of warning before password expires"]),
|
||||
passwordage: dayslastset,
|
||||
badpasswordattempts: badpasswordattempts,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
@ -481,6 +528,8 @@ module Inspec::Resources
|
|||
mindays: user_sec[1].to_i * 7,
|
||||
maxdays: user_sec[2].to_i * 7,
|
||||
warndays: user_sec[3].to_i,
|
||||
passwordage: nil,
|
||||
badpasswordattempts: nil,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
@ -573,6 +622,31 @@ module Inspec::Resources
|
|||
res[0] unless res.empty?
|
||||
end
|
||||
|
||||
def meta_info(username)
|
||||
res = identity(username)
|
||||
return if res.nil?
|
||||
{
|
||||
home: res[:home],
|
||||
shell: res[:shell],
|
||||
domain: res[:domain],
|
||||
userflags: res[:userflags],
|
||||
}
|
||||
end
|
||||
|
||||
def credentials(username)
|
||||
res = identity(username)
|
||||
return if res.nil?
|
||||
{
|
||||
mindays: res[:mindays],
|
||||
maxdays: res[:maxdays],
|
||||
warndays: res[:warndays],
|
||||
badpasswordattempts: res[:badpasswordattempts],
|
||||
maxbadpasswords: res[:maxbadpasswords],
|
||||
minpasswordlength: res[:minpasswordlength],
|
||||
passwordage: res[:passwordage],
|
||||
}
|
||||
end
|
||||
|
||||
def list_users
|
||||
collect_user_details.map { |user| user[:username] }
|
||||
end
|
||||
|
|
2
lib/inspec/resources/windows_registry_key.rb
Normal file
2
lib/inspec/resources/windows_registry_key.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This is just here to make the dynamic loader happy.
|
||||
require "inspec/resources/registry_key.rb"
|
|
@ -59,7 +59,7 @@ module Inspec::Resources
|
|||
# detect repo start
|
||||
in_repo = true if line =~ /^\s*Repo-id\s*:\s*(.*)\b/
|
||||
# detect repo end
|
||||
if line == "\n" && in_repo
|
||||
if (line == "\n" || line =~ /\s*Total packages:/) && in_repo
|
||||
in_repo = false
|
||||
@cache.push(repo)
|
||||
repo = {}
|
||||
|
@ -70,6 +70,9 @@ module Inspec::Resources
|
|||
repo[repo_key(strip(val[1]))] = strip(val[2])
|
||||
end
|
||||
end
|
||||
|
||||
@cache.push(repo) if in_repo
|
||||
|
||||
@cache
|
||||
end
|
||||
|
||||
|
|
|
@ -10,6 +10,15 @@ module Inspec
|
|||
module DescribeDslLazyLoader
|
||||
# Support for Describe DSL plugins
|
||||
def method_missing(method_name, *arguments, &block)
|
||||
# TODO: need a backend available at the describe level... class method somewhere?
|
||||
# # see if it is a resource first
|
||||
# begin
|
||||
# resource = Inspec::DSL.method_missing_resource(:where_is_backend?, method_name, *arguments)
|
||||
# return resource if resource
|
||||
# rescue LoadError
|
||||
# # pass through
|
||||
# end
|
||||
|
||||
# Check to see if there is a describe_dsl plugin activator hook with the method name
|
||||
registry = Inspec::Plugin::V2::Registry.instance
|
||||
hook = registry.find_activators(plugin_type: :describe_dsl, activator_name: method_name).first
|
||||
|
@ -39,6 +48,15 @@ module Inspec
|
|||
module TestDslLazyLoader
|
||||
# Support for test DSL plugins
|
||||
def method_missing(method_name, *arguments, &block)
|
||||
# see if it is a resource first
|
||||
begin
|
||||
backend = inspec if respond_to?(:inspec) # backend not available??
|
||||
resource = Inspec::DSL.method_missing_resource(backend, method_name, *arguments)
|
||||
return resource if resource
|
||||
rescue LoadError
|
||||
# pass through
|
||||
end
|
||||
|
||||
# Check to see if there is a test_dsl plugin activator hook with the method name
|
||||
registry = Inspec::Plugin::V2::Registry.instance
|
||||
hook = registry.find_activators(plugin_type: :test_dsl, activator_name: method_name).first
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require "method_source"
|
||||
require "date"
|
||||
require "inspec/describe"
|
||||
require "inspec/describe_base"
|
||||
require "inspec/expect"
|
||||
require "inspec/resource"
|
||||
require "inspec/resources/os"
|
||||
|
@ -60,7 +60,7 @@ module Inspec
|
|||
# waivers have higher precedence than only_if.
|
||||
__apply_waivers
|
||||
|
||||
rescue StandardError => e
|
||||
rescue SystemStackError, StandardError => e
|
||||
# We've encountered an exception while trying to eval the code inside the
|
||||
# control block. We need to prevent the exception from bubbling up, and
|
||||
# fail the control. Controls are failed by having a failed resource within
|
||||
|
@ -227,9 +227,7 @@ module Inspec
|
|||
msg = "Skipped control due to #{skip_check[:type]} condition."
|
||||
end
|
||||
|
||||
# TODO: we use os as the carrier here, but should consider
|
||||
# a separate resource to do skipping
|
||||
resource = rule.os
|
||||
resource = rule.noop
|
||||
resource.skip_resource(msg)
|
||||
[["describe", [resource], nil]]
|
||||
end
|
||||
|
@ -299,11 +297,11 @@ module Inspec
|
|||
__waiver_data["skipped_due_to_waiver"] = false
|
||||
__waiver_data["message"] = ""
|
||||
|
||||
# Waivers should have a hash value with keys possibly including skip and
|
||||
# expiration_date. We only care here if it has a skip key and it
|
||||
# is yes-like, since all non-skipped waiver operations are handled
|
||||
# Waivers should have a hash value with keys possibly including "run" and
|
||||
# expiration_date. We only care here if it has a "run" key and it
|
||||
# is false-like, since all non-skipped waiver operations are handled
|
||||
# during reporting phase.
|
||||
return unless __waiver_data.key?("skip") && __waiver_data["skip"]
|
||||
return unless __waiver_data.key?("run") && !__waiver_data["run"]
|
||||
|
||||
# OK, the intent is to skip. Does it have an expiration date, and
|
||||
# if so, is it in the future?
|
||||
|
@ -344,14 +342,13 @@ module Inspec
|
|||
def with_dsl(block)
|
||||
return nil if block.nil?
|
||||
|
||||
if self.class.resource_dsl
|
||||
dsl = self.class.resource_dsl
|
||||
proc do |*args|
|
||||
include dsl
|
||||
instance_exec(*args, &block)
|
||||
end
|
||||
else
|
||||
block
|
||||
dsl = self.class.resource_dsl
|
||||
|
||||
return block unless dsl
|
||||
|
||||
proc do |*args|
|
||||
include dsl
|
||||
instance_exec(*args, &block)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ module Inspec
|
|||
attr_reader :backend, :rules
|
||||
attr_accessor :target_profiles
|
||||
|
||||
attr_accessor :test_collector
|
||||
|
||||
def attributes
|
||||
Inspec.deprecate(:rename_attributes_to_inputs, "Don't call runner.attributes, call runner.inputs")
|
||||
inputs
|
||||
|
|
|
@ -83,7 +83,7 @@ module Inspec
|
|||
return @rspec_exit_code if @formatter.results.empty?
|
||||
|
||||
stats = @formatter.results[:statistics][:controls]
|
||||
skipped = @formatter.results&.fetch(:profiles, nil)&.first&.fetch(:status, nil) == "skipped"
|
||||
skipped = @formatter.results.dig(:profiles, 0, :status) == "skipped"
|
||||
if stats[:failed][:total] == 0 && stats[:skipped][:total] == 0 && !skipped
|
||||
0
|
||||
elsif stats[:failed][:total] > 0
|
||||
|
|
|
@ -96,6 +96,16 @@ module Inspec
|
|||
},
|
||||
},
|
||||
"results" => { "type" => "array", "items" => RESULT },
|
||||
"waiver_data" => {
|
||||
"type" => "object",
|
||||
"properties" => {
|
||||
"skipped_due_to_waiver" => { "type" => "string" },
|
||||
"run" => { "type" => "boolean" },
|
||||
"message" => { "type" => "string" },
|
||||
"expiration_date" => { "type" => "string" },
|
||||
"justification" => { "type" => "string" },
|
||||
},
|
||||
},
|
||||
},
|
||||
}.freeze
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class NginxParser < Parslet::Parser
|
|||
end
|
||||
|
||||
rule(:standard_identifier) do
|
||||
(match("[a-zA-Z]") >> match('\S').repeat).as(:identifier) >> space >> space.repeat
|
||||
(match("[a-zA-Z~*.]") >> match('\S').repeat).as(:identifier) >> space >> space.repeat
|
||||
end
|
||||
|
||||
rule(:quoted_identifier) do
|
||||
|
|
|
@ -20,13 +20,14 @@ module PasswdParser
|
|||
def parse_passwd_line(line)
|
||||
x = line.split(":")
|
||||
{
|
||||
"user" => x.at(0),
|
||||
"password" => x.at(1),
|
||||
"uid" => x.at(2),
|
||||
"gid" => x.at(3),
|
||||
"desc" => x.at(4),
|
||||
"home" => x.at(5),
|
||||
"shell" => x.at(6),
|
||||
# rubocop:disable Layout/AlignHash
|
||||
"user" => x[0],
|
||||
"password" => x[1],
|
||||
"uid" => x[2],
|
||||
"gid" => x[3],
|
||||
"desc" => x[4],
|
||||
"home" => x[5],
|
||||
"shell" => x[6],
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
module Inspec
|
||||
VERSION = "4.17.5".freeze
|
||||
VERSION = "4.18.26".freeze
|
||||
end
|
||||
|
|
|
@ -152,7 +152,7 @@ $ inspec exec compliance://admin/profile
|
|||
|
||||
Pending: (Failures listed here are expected and do not affect your suite's status)
|
||||
|
||||
1) gordon_config Can't find file "/tmp/gordon/config.yaml"
|
||||
1) example_config Can't find file "/tmp/example/config.yaml"
|
||||
# Not yet implemented
|
||||
# ./lib/inspec/runner.rb:157
|
||||
|
||||
|
|
|
@ -72,10 +72,10 @@ module InspecPlugins
|
|||
desc "exec PROFILE", "executes a #{COMPLIANCE_PRODUCT_NAME} profile"
|
||||
exec_options
|
||||
def exec(*tests)
|
||||
config = InspecPlugins::Compliance::Configuration.new
|
||||
return unless loggedin(config)
|
||||
compliance_config = InspecPlugins::Compliance::Configuration.new
|
||||
return unless loggedin(compliance_config)
|
||||
|
||||
o = opts(:exec).dup
|
||||
o = config # o is an Inspec::Config object, provided by a helper method from Inspec::BaseCLI
|
||||
diagnose(o)
|
||||
configure_logger(o)
|
||||
|
||||
|
|
|
@ -58,18 +58,18 @@ describe InspecPlugins::Compliance::API do
|
|||
it "raises an error if `--user` is missing" do
|
||||
options = automate_options
|
||||
options.delete("user")
|
||||
err = proc { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
err.message.must_match(/Please specify a user.*/)
|
||||
err.message.lines.length.must_equal(1)
|
||||
err = _ { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
_(err.message).must_match(/Please specify a user.*/)
|
||||
_(err.message.lines.length).must_equal(1)
|
||||
end
|
||||
|
||||
it "raises an error if `--token` and `--dctoken` are missing" do
|
||||
options = automate_options
|
||||
options.delete("token")
|
||||
options.delete("dctoken")
|
||||
err = proc { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
err.message.must_match(/Please specify a token.*/)
|
||||
err.message.lines.length.must_equal(1)
|
||||
err = _ { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
_(err.message).must_match(/Please specify a token.*/)
|
||||
_(err.message.lines.length).must_equal(1)
|
||||
end
|
||||
|
||||
it "stores an access token" do
|
||||
|
@ -79,12 +79,12 @@ describe InspecPlugins::Compliance::API do
|
|||
InspecPlugins::Compliance::Configuration.expects(:new).returns(fake_config)
|
||||
|
||||
InspecPlugins::Compliance::API.login(options)
|
||||
fake_config["automate"]["ent"].must_equal("automate")
|
||||
fake_config["automate"]["token_type"].must_equal("dctoken")
|
||||
fake_config["user"].must_equal("someone")
|
||||
fake_config["server"].must_equal("https://automate.example.com/api/v0")
|
||||
fake_config["server_type"].must_equal("automate2")
|
||||
fake_config["token"].must_equal("token")
|
||||
_(fake_config["automate"]["ent"]).must_equal("automate")
|
||||
_(fake_config["automate"]["token_type"]).must_equal("dctoken")
|
||||
_(fake_config["user"]).must_equal("someone")
|
||||
_(fake_config["server"]).must_equal("https://automate.example.com/api/v0")
|
||||
_(fake_config["server_type"]).must_equal("automate2")
|
||||
_(fake_config["token"]).must_equal("token")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -96,26 +96,26 @@ describe InspecPlugins::Compliance::API do
|
|||
it "raises an error if `--user` is missing" do
|
||||
options = automate_options
|
||||
options.delete("user")
|
||||
err = proc { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
err.message.must_match(/Please specify a user.*/)
|
||||
err.message.lines.length.must_equal(1)
|
||||
err = _ { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
_(err.message).must_match(/Please specify a user.*/)
|
||||
_(err.message.lines.length).must_equal(1)
|
||||
end
|
||||
|
||||
it "raises an error if `--ent` is missing" do
|
||||
options = automate_options
|
||||
options.delete("ent")
|
||||
err = proc { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
err.message.must_match(/Please specify an enterprise.*/)
|
||||
err.message.lines.length.must_equal(1)
|
||||
err = _ { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
_(err.message).must_match(/Please specify an enterprise.*/)
|
||||
_(err.message.lines.length).must_equal(1)
|
||||
end
|
||||
|
||||
it "raises an error if `--token` and `--dctoken` are missing" do
|
||||
options = automate_options
|
||||
options.delete("token")
|
||||
options.delete("dctoken")
|
||||
err = proc { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
err.message.must_match(/Please specify a token.*/)
|
||||
err.message.lines.length.must_equal(1)
|
||||
err = _ { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
_(err.message).must_match(/Please specify a token.*/)
|
||||
_(err.message.lines.length).must_equal(1)
|
||||
end
|
||||
|
||||
it "stores an access token" do
|
||||
|
@ -125,12 +125,12 @@ describe InspecPlugins::Compliance::API do
|
|||
InspecPlugins::Compliance::Configuration.expects(:new).returns(fake_config)
|
||||
|
||||
InspecPlugins::Compliance::API.login(options)
|
||||
fake_config["automate"]["ent"].must_equal("automate")
|
||||
fake_config["automate"]["token_type"].must_equal("usertoken")
|
||||
fake_config["user"].must_equal("someone")
|
||||
fake_config["server"].must_equal("https://automate.example.com/compliance")
|
||||
fake_config["server_type"].must_equal("automate")
|
||||
fake_config["token"].must_equal("token")
|
||||
_(fake_config["automate"]["ent"]).must_equal("automate")
|
||||
_(fake_config["automate"]["token_type"]).must_equal("usertoken")
|
||||
_(fake_config["user"]).must_equal("someone")
|
||||
_(fake_config["server"]).must_equal("https://automate.example.com/compliance")
|
||||
_(fake_config["server_type"]).must_equal("automate")
|
||||
_(fake_config["token"]).must_equal("token")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -143,9 +143,9 @@ describe InspecPlugins::Compliance::API do
|
|||
options = automate_options
|
||||
options.delete("user")
|
||||
options.delete("refresh_token")
|
||||
err = proc { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
err.message.must_match(/Please specify a.*--user.*--refresh-token.*/)
|
||||
err.message.lines.length.must_equal(1)
|
||||
err = _ { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
_(err.message).must_match(/Please specify a.*--user.*--refresh-token.*/)
|
||||
_(err.message.lines.length).must_equal(1)
|
||||
end
|
||||
|
||||
it "raises an error if `--user` is present but authentication method missing" do
|
||||
|
@ -153,9 +153,9 @@ describe InspecPlugins::Compliance::API do
|
|||
options.delete("password")
|
||||
options.delete("token")
|
||||
options.delete("refresh_token")
|
||||
err = proc { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
err.message.must_match(/Please specify.*--password.*--token.*--refresh-token.*/)
|
||||
err.message.lines.length.must_equal(1)
|
||||
err = _ { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
_(err.message).must_match(/Please specify.*--password.*--token.*--refresh-token.*/)
|
||||
_(err.message.lines.length).must_equal(1)
|
||||
end
|
||||
|
||||
it "stores an access token" do
|
||||
|
@ -165,25 +165,25 @@ describe InspecPlugins::Compliance::API do
|
|||
InspecPlugins::Compliance::Configuration.expects(:new).returns(fake_config)
|
||||
|
||||
InspecPlugins::Compliance::API.login(options)
|
||||
fake_config["user"].must_equal("someone")
|
||||
fake_config["server"].must_equal("https://compliance.example.com/api")
|
||||
fake_config["server_type"].must_equal("compliance")
|
||||
fake_config["token"].must_equal("token")
|
||||
_(fake_config["user"]).must_equal("someone")
|
||||
_(fake_config["server"]).must_equal("https://compliance.example.com/api")
|
||||
_(fake_config["server_type"]).must_equal("compliance")
|
||||
_(fake_config["token"]).must_equal("token")
|
||||
end
|
||||
end
|
||||
|
||||
describe "when target is neither a Chef Compliance nor Chef Automate server" do
|
||||
it "raises an error if `https://SERVER` is missing" do
|
||||
options = {}
|
||||
err = proc { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
err.message.must_match(/Please specify a server.*/)
|
||||
err.message.lines.length.must_equal(1)
|
||||
err = _ { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
|
||||
_(err.message).must_match(/Please specify a server.*/)
|
||||
_(err.message.lines.length).must_equal(1)
|
||||
end
|
||||
|
||||
it "rasies a `CannotDetermineServerType` error" do
|
||||
InspecPlugins::Compliance::API.expects(:determine_server_type).returns(nil)
|
||||
err = proc { InspecPlugins::Compliance::API.login(automate_options) }.must_raise(StandardError)
|
||||
err.message.must_match(/Unable to determine/)
|
||||
err = _ { InspecPlugins::Compliance::API.login(automate_options) }.must_raise(StandardError)
|
||||
_(err.message).must_match(/Unable to determine/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue