Merge remote-tracking branch 'upstream/master' into add-startuser-systemd-service

Signed-off-by: Mendy Baitelman <mendy@baitelman.com>
This commit is contained in:
Mendy Baitelman 2019-11-04 21:07:56 -08:00
commit 1a9a47ee96
360 changed files with 4272 additions and 2755 deletions

View file

@ -1,5 +1,6 @@
[inspec]
build_targets = [
"x86_64-windows",
"x86_64-linux",
"x86_64-linux-kernel2"
]
]

View file

@ -26,3 +26,6 @@ plugins:
enabled: true
exclude_patterns:
- "www/source/javascripts/"
- "examples/"
- "test/unit/mock/profiles/"
- "test/kitchen"

View 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

View 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}"

View 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

View 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

View file

@ -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:-}

View file

@ -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

View file

@ -0,0 +1 @@
#

View file

@ -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

View file

@ -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

View file

@ -1,5 +1,6 @@
AllCops:
Exclude:
- 'test/kitchen/**/*'
- 'test/integration/**/controls/**/*.rb'
- 'test/unit/mock/profiles/**/*.rb'
- 'test/unit/mock/config_dirs/**/*.rb'

View file

@ -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 -&gt; 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 &quot;an Chef Inspec&quot; to &quot;a Chef Inspec&quot;. [#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&#39;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 &#39;normal&#39; 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&#39;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&#39;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 &#39;group&#39; 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 -&gt; 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)

View file

@ -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

View file

@ -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"

View file

@ -1 +1 @@
4.17.5
4.18.26

120
docs/dev/compliance.md Normal file
View 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.

View file

@ -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

View file

@ -17,7 +17,7 @@ $ tree examples/profile
examples/profile
...
├── libraries
│   └── gordon_config.rb
│   └── example_config.rb
```
## Resource structure
@ -51,8 +51,8 @@ The following example shows a full resource using attributes and methods
to provide simple access to a configuration file:
```ruby
class GordonConfig < Inspec.resource(1)
name 'gordon_config'
class ExampleConfig < Inspec.resource(1)
name 'example_config'
# Restrict to only run on the below platforms (if none were given, all OS's supported)
supports platform_family: 'fedora'
@ -65,14 +65,14 @@ class GordonConfig < Inspec.resource(1)
'
example '
describe gordon_config do
describe example_config do
its("signal") { should eq "on" }
end
'
# Load the configuration file on initialization
def initialize(path = nil)
@path = path || '/etc/gordon.conf'
@path = path || '/etc/example.conf'
@params = SimpleConfig.new( read_content )
end
@ -90,11 +90,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.

View file

@ -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
```
```

View file

@ -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

View file

@ -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

View file

@ -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(...)`.

View 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).

View file

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

View file

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

View file

@ -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.

View file

@ -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.

View file

@ -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
View 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
```

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

102
habitat/plan.ps1 Normal file
View 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
}

View 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
View 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

View file

@ -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

View file

@ -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"

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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?

View file

@ -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

View file

@ -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
#--------------------------------------------------------------------------#

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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),
}
}

View file

@ -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.

View file

@ -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)

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/service"

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/etc_hosts_allow_deny"

View file

@ -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

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/etc_hosts_allow_deny"

View file

@ -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}"

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/groups"

View file

@ -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

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/iis_website.rb"

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/service"

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/kernel_parameter"

View file

@ -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

View file

@ -0,0 +1,9 @@
module Inspec::Resources
class Noop < Inspec.resource(1)
name "noop"
def to_s
"No-op"
end
end
end

View file

@ -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>", "")

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/parse_config"

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/apt.rb"

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/rabbitmq_config.rb"

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/service"

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/ssh_config.rb"

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/service"

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/service"

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/service"

View file

@ -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

View file

@ -0,0 +1,2 @@
# This is just here to make the dynamic loader happy.
require "inspec/resources/registry_key.rb"

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1,3 +1,3 @@
module Inspec
VERSION = "4.17.5".freeze
VERSION = "4.18.26".freeze
end

View file

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

View file

@ -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)

View file

@ -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