Markdown and code fence fixes (#3230)

Signed-off-by: kgarmoe <kgarmoe@chef.io>
This commit is contained in:
Kimberly Garmoe 2018-07-19 11:31:38 -07:00 committed by Jared Quick
parent 9581176633
commit eb87fd384d
9 changed files with 307 additions and 235 deletions

View file

@ -45,16 +45,15 @@ where
* `'sshd-8'` is the name of the control
* `impact`, `title`, and `desc` define metadata that fully describes the importance of the control, its purpose, with a succinct and complete description
* `impact` is an float that measures the importance of the compliance results and must be a value between `0.0` and `1.0`. The value ranges are:
* `0.0 to <0.4` these are controls with minor criticality
* `0.4 to <0.7` these are controls with major criticality
* `0.7 to 1.0` these are critical controls
* `0.0 to <0.4` these are controls with minor criticality
* `0.4 to <0.7` these are controls with major criticality
* `0.7 to 1.0` these are critical controls
* `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 InSpec resource. For the full list of InSpec resources, see 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
With InSpec it is possible to check if at least one of a collection of checks is true. For example: If a setting is configured in two different locations, you may want to test if either configuration A or configuration B have been set. This is accomplished via `describe.one`. It defines a block of tests with at least one valid check.
@ -71,7 +70,7 @@ describe.one do
end
```
#### Sensitive resources
### Sensitive resources
In some scenarios, you may be writing checks involving resources with sensitive content (e.g. a file resource). In the case of failures, it may be desired to suppress output. This can be done by adding the `:sensitive` flag to the resource definition
@ -100,7 +99,7 @@ control 'windows-account-102' do
end
```
## Are PostgreSQL passwords empty?
## Test if PostgreSQL passwords are empty
The following test shows how to audit machines running PostgreSQL to ensure that passwords are not empty.
@ -114,7 +113,7 @@ control 'postgres-7' do
end
```
## Are MySQL passwords in ENV?
## Test if MySQL passwords are in ENV
The following test shows how to audit machines running MySQL to ensure that passwords are not stored in `ENV`:
@ -132,7 +131,7 @@ control 'mysql-3' do
end
```
## Is `/etc/ssh` a Directory?
## Test if `/etc/ssh` is a Directory
The following test shows how to audit machines to ensure that `/etc/ssh` is a directory:
@ -150,7 +149,7 @@ control 'basic-1' do
end
```
## Is Apache running?
## Test if Apache running
The following test shows how to audit machines to ensure that Apache is enabled and running:
@ -165,7 +164,7 @@ control 'apache-1' do
end
```
## Are insecure packages installed ?
## Test if insecure packages are installed
The following test shows how to audit machines for insecure packages:
@ -223,7 +222,6 @@ Mixing this with other conditionals (like checking existence of the files etc.)
## Additional metadata for controls
The following example illustrates various ways to add tags and references to `control`
```ruby

View file

@ -11,7 +11,7 @@ There are two ways to use it:
### Motivating Example
Suppose we are interested in auditing cars. Let's suppose we have two InSpec resources for auditing: `cars`, which searchs for and filters groups of cars, and `car`, which performs detailed auditing of a single car.
Suppose we are interested in auditing cars. Let's suppose we have two InSpec resources for auditing: `cars`, which searches for and filters groups of cars, and `car`, which performs detailed auditing of a single car.
### Basic Syntax
@ -134,7 +134,7 @@ A [resource](#resource) that is _not_ included with InSpec. It may be a resource
The _`describe`_ keyword is used with a _`describe block`_ to refer to an 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
# Count only blue cars
describe cars.where(color: 'blue') do
@ -155,7 +155,7 @@ When using a [matcher](#matcher), the _`expected result`_ is the value the match
In this example, the [`cmp`](https://www.inspec.io/docs/reference/matchers/#cmp) matcher is being used to compare the `color` property to the expected result 'black'.
```
```Ruby
describe car(owner: 'Bruce Wayne') do
its('color') { should cmp 'black' }
end
@ -169,7 +169,7 @@ A filter statement may use method call syntax (which allows basic criteria opera
In this example, `where(...)` is the filter statement.
```
```Ruby
# Count only blue cars
describe cars.where(color: 'blue') do
its('count') { should eq 20 }
@ -186,7 +186,7 @@ When method-call syntax is used with the filter statement, you provide filter cr
Here, `(color: blue)` is a single filter criterion being used with a filter statement in method-call syntax.
```
```Ruby
# Count only blue cars
describe cars.where(color: 'blue') do
its('count') { should eq 20 }
@ -197,7 +197,7 @@ When block-method syntax is used with the filter statement, you provide a block.
Here, `{ engine_cylinders >= 6 }` is a block-syntax filter statement referring to one filter criterion.
```
```Ruby
# Vroom!
describe cars.where { engine_cylinders >= 6 } do
its('city_mpg_ratings') { should_not include '4-star' }
@ -212,7 +212,7 @@ Within a [describe block](#describe), _`it`_ declares an individual [test](#test
Here, `it { should ... }` declares a test, calling the `classy?` matcher on Tony Clifton's car.
```
```Ruby
describe car(owner: 'Tony Clifton') do
it { should be_classy }
end
@ -228,7 +228,7 @@ The property to access is passed as a single string argument to `its`. As an adv
Here, `its('fuzzy_dice') { should ... }` declares a test, testing against the `fuzzy_dice` property of Tony Clifton's car. Let's assume - Tony being Tony - that `fuzzy_dice` will return an Array.
```
```Ruby
describe car(owner: 'Tony Clifton') do
its('fuzzy_dice') { should_not be_empty }
its('fuzzy_dice.count') { should be >= 2 }
@ -249,7 +249,7 @@ For information on how RSpec matchers are related o InSpec matchers, see [InSpec
Here, `be_classy` is a resource-specific matcher operating directly on the `car`, while `cmp` is a universal matcher operating on the `manufacturer` property.
```
```Ruby
describe car(owner: 'Tony Clifton') do
it { should be_classy }
its('manufacturer') { should cmp 'Cadillac' }
@ -266,7 +266,7 @@ Plural resources support [filter statements](#filter_statement). See the [resour
Here, `cars` is a plural resource.
```
```Ruby
describe cars.where(color: 'blue') do
its('count') { should eq 20 }
its('license_plates') { should include 'AUTOAZUL' }
@ -296,7 +296,7 @@ Each resource has different properties. See the [resource documentation](https:/
Here, `manufacturer` is a property of the `car` resource.
```
```Ruby
describe car(owner: 'Tony Clifton') do
its('manufacturer') { should cmp 'Cadillac' }
end
@ -316,7 +316,7 @@ Resources are used within a [describe block](#describe_block) to perform [tests]
Here, `car` is a resource.
```
```Ruby
describe car(owner: 'Tony Clifton') do
it { should be_classy }
end
@ -334,7 +334,7 @@ Resource parameters vary from resource to resource; refer to the [resource docum
Here, `owner: 'Tony Clifton'` is a resource parameter.
```
```Ruby
describe car(owner: 'Tony Clifton') do
it { should be_classy }
end
@ -348,7 +348,7 @@ Resource-specific matchers often provide highly customized behavior. Check the [
For example, the hypothetical `car` resource defines a `classy?` method, which is exposed as the `be_classy` matcher in InSpec tests.
```
```Ruby
describe car(owner: 'Tony Clifton') do
it { should be_classy }
end
@ -374,7 +374,7 @@ Universal matchers are documented on the [Universal Matchers](https://www.inspec
Here, we access the 'color' property, then use the `cmp` universal matcher to compare the property to the 'black' [expected result](#expected_result).
```
```Ruby
describe car(owner: 'Bruce Wayne') do
its('color') { should cmp 'black' }
end

View file

@ -6,7 +6,7 @@ title: InSpec Integration with Habitat
InSpec provides an easy method to create an executable Habitat package for an InSpec profile. When run via the Habitat Supervisor, the package will run InSpec with your profile and write out its findings to a JSON file. This provides the ability to ship your compliance controls alongside your Habitat-packaged application and continuously run InSpec, providing you *Continuous Compliance.*
## What is Habitat?
## What is Habitat
Habitat by Chef is our new Application Automation tool that aims to make it easy, safe, and fast to build, deploy, and manage applications. From build dependencies, runtime dependencies, dynamic configuration, and service discovery (just to name a few), Habitat packages the automation with the application instead of relying on an underlying platform.
@ -28,7 +28,7 @@ HAB_INSPEC_PROFILE_FRONTEND1="sleep_time = 60" hab start adamleff/inspec-profile
The Habitat Supervisor will display output like this:
```
```text
hab start adamleff/inspec-profile-frontend1
∵ Missing package for core/hab-sup/0.17.0
» Installing core/hab-sup/0.17.0
@ -62,7 +62,7 @@ The above sample output shows the supervisor starting, downloading the necessary
InSpec will write a JSON file in the `${svc_var_path}/inspec_results` directory containing the results of the last InSpec run. For example, for the `adamleff/inspec-profile-frontend1` package, the InSpec results will be at:
```
```text
/hab/svc/inspec-profile-frontend1/var/inspec_results/inspec-profile-frontend1.json
```
@ -74,13 +74,13 @@ Create a Habitat package for an InSpec profile. InSpec will validate the profile
The package file will be named:
```
```text
HABITAT_ORIGIN-inspec-profile-PROFILE_NAME-PROFILE_VERSION-BUILD_ID-x86_64-linux.hart
```
For example:
```
```text
adamleff-inspec-profile-frontend1-0.1.0-20170328173005-x86_64-linux.hart
```
@ -104,13 +104,13 @@ The package can then be manually uploaded to a Habitat Depot or manually distrib
The package file will be named:
```
```text
HABITAT_ORIGIN-inspec-profile-PROFILE_NAME-PROFILE_VERSION-BUILD_ID-x86_64-linux.hart
```
For example:
```
```text
adamleff-inspec-profile-frontend1-0.1.0-20170328173005-x86_64-linux.hart
```
@ -128,7 +128,7 @@ inspec habitat profile create ~/profiles/frontend1
#### Example Output
```
```text
$ habitat profile create ~/profiles/frontend1
[2017-03-28T13:29:32-04:00] INFO: Creating a Habitat artifact for profile: /Users/aleff/profiles/frontend1
[2017-03-28T13:29:32-04:00] INFO: Checking to see if Habitat is installed...
@ -168,7 +168,8 @@ inspec habitat profile upload ~/profiles/frontend1
```
#### Example Output
```
```text
[2017-03-28T13:29:32-04:00] INFO: Creating a Habitat artifact for profile: /Users/aleff/profiles/frontend1
[2017-03-28T13:29:32-04:00] INFO: Checking to see if Habitat is installed...
[2017-03-28T13:29:32-04:00] INFO: Copying profile contents to the work directory...

View file

@ -42,10 +42,10 @@ end
That said, InSpec is not RSpec. Some key differences:
* In InSpec, `describe` blocks should not be nested; instead use `control` blocks to describe a higher-level grouping of tests.
* The RSpec `shared_example` construct is not supported. Instead, create a simple custom resource that executes repetitious tasks.
* InSpec is aimed at compliance practitioners and infrastructure testers, so our focus is providing a few, well-supported, easy-to-use [universal matchers](https://www.inspec.io/docs/reference/matchers/), such as `cmp`. In contrast, RSpec is a tool designed for software engineers. It thus supports a very large range of matchers, to enable testing of software engineering constructs such as exceptions, Object Oriented Programming relationships, and so on.
* While InSpec uses parts of the RSpec project and codebase, it is a separate project from InSpec. Rspec's release schedule and feature set are beyond the control of the InSpec team. While it is possible to use many of the RSpec core features within InSpec profiles, InSpec can only guarantee that the features described at [docs.inspec.io](https://docs.inspec.io) will function correctly. Some RSpec core functionality may be removed in future versions of InSpec as needed to ensure stability in the InSpec project.
* In InSpec, `describe` blocks should not be nested; instead use `control` blocks to describe a higher-level grouping of tests.
* The RSpec `shared_example` construct is not supported. Instead, create a simple custom resource that executes repetitious tasks.
* InSpec is aimed at compliance practitioners and infrastructure testers, so our focus is providing a few, well-supported, easy-to-use [universal matchers](https://www.inspec.io/docs/reference/matchers/), such as `cmp`. In contrast, RSpec is a tool designed for software engineers. It thus supports a very large range of matchers, to enable testing of software engineering constructs such as exceptions, Object Oriented Programming relationships, and so on.
* While InSpec uses parts of the RSpec project and codebase, it is a separate project from InSpec. Rspec's release schedule and feature set are beyond the control of the InSpec team. While it is possible to use many of the RSpec core features within InSpec profiles, InSpec can only guarantee that the features described at [docs.inspec.io](https://docs.inspec.io) will function correctly. Some RSpec core functionality may be removed in future versions of InSpec as needed to ensure stability in the InSpec project.
## Serverspec

View file

@ -32,8 +32,6 @@ describe file('/proc/cpuinfo') do
end
```
<br>
## cmp
Unlike `eq`, `cmp` is a matcher for less-restrictive comparisons. It will
@ -72,6 +70,7 @@ describe auditd_conf do
its('log_format') { should cmp 'RAW' }
end
```
* Recognize versions embedded in strings
```ruby
@ -107,7 +106,6 @@ end
expected: 0345
got: 0444
```
<br>
## eq
@ -132,8 +130,6 @@ its('Port') { should eq 22 }
For less restrictive comparisons, please use `cmp`.
<br>
## include
Verifies if a value is included in a list.
@ -144,8 +140,6 @@ describe passwd do
end
```
<br>
## be_in
Verifies that an item is included in a list.
@ -156,8 +150,6 @@ describe resource do
end
```
<br>
## match
Check if a string matches a regular expression.

View file

@ -8,43 +8,53 @@ Use InSpec as a Kitchen verifier with `kitchen-inspec`.
Add the InSpec verifier to the `.kitchen.yml` file:
verifier:
name: inspec
```YML
verifier:
name: inspec
```
Use a compliance profile from the Chef Compliance server:
suites:
- name: compliance
run_list:
- recipe[ssh-hardening::default]
verifier:
inspec_tests:
- compliance://base/ssh
```YML
suites:
- name: compliance
run_list:
- recipe[ssh-hardening::default]
verifier:
inspec_tests:
- compliance://base/ssh
```
and then run the following command:
$ inspec compliance login https://compliance.test --user admin --insecure --token ''
```bash
$ inspec compliance login https://compliance.test --user admin --insecure --token ''
```
where `--insecure` is required when using self-signed certificates.
Use a compliance profile from the Chef Supermarket:
suites:
- name: supermarket
run_list:
- recipe[ssh-hardening::default]
verifier:
inspec_tests:
- supermarket://dev-sec/ssh-baseline
```YML
suites:
- name: supermarket
run_list:
- recipe[ssh-hardening::default]
verifier:
inspec_tests:
- supermarket://dev-sec/ssh-baseline
```
Use InSpec tests from the local file system:
suites:
- name: local
run_list:
- recipe[my_cookbook::default]
verifier:
inspec_tests:
- test/integration/default
```YML
suites:
- name: local
run_list:
- recipe[my_cookbook::default]
verifier:
inspec_tests:
- test/integration/default
```
Check out [Detect and correct with Test Kitchen](https://learn.chef.io/modules/detect-correct-kitchen#/) on Learn Chef Rally for a hands-on look at how to use Test Kitchen to run InSpec profiles.

View file

@ -10,16 +10,18 @@ InSpec supports the creation of complex test and compliance profiles, which orga
A profile should have the following structure::
examples/profile
├── README.md
├── controls
│ ├── example.rb
│ └── control_etc.rb
├── libraries
│ └── extension.rb
|── files
│ └── extras.conf
└── inspec.yml
```YAML
examples/profile
├── README.md
├── controls
│ ├── example.rb
│ └── control_etc.rb
├── libraries
│ └── extension.rb
|── files
│ └── extras.conf
└── inspec.yml
```
where:
@ -37,79 +39,92 @@ Also check out [Explore InSpec resources](https://learn.chef.io/modules/explore-
Each profile must have an `inspec.yml` file that defines the following information:
* Use `name` to specify a unique name for the profile. Required.
* Use `title` to specify a human-readable name for the profile.
* Use `maintainer` to specify the profile maintainer.
* Use `copyright` to specify the copyright holder.
* Use `copyright_email` to specify support contact information for the profile, typically an email address.
* Use `license` to specify the license for the profile.
* Use `summary` to specify a one line summary for the profile.
* Use `description` to specify a multiple line description of the profile.
* Use `version` to specify the profile version.
* Use `inspec_version` to place SemVer constraints on the version of InSpec that the profile can run under.
* Use `supports` to specify a list of supported platform targets.
* Use `depends` to define a list of profiles on which this profile depends.
* Use `name` to specify a unique name for the profile. Required.
* Use `title` to specify a human-readable name for the profile.
* Use `maintainer` to specify the profile maintainer.
* Use `copyright` to specify the copyright holder.
* Use `copyright_email` to specify support contact information for the profile, typically an email address.
* Use `license` to specify the license for the profile.
* Use `summary` to specify a one line summary for the profile.
* Use `description` to specify a multiple line description of the profile.
* Use `version` to specify the profile version.
* Use `inspec_version` to place SemVer constraints on the version of InSpec that the profile can run under.
* Use `supports` to specify a list of supported platform targets.
* Use `depends` to define a list of profiles on which this profile depends.
`name` is required; all other profile settings are optional. For example:
name: ssh
title: Basic SSH
maintainer: Chef Software, Inc.
copyright: Chef Software, Inc.
copyright_email: support@chef.io
license: Proprietary, All rights reserved
summary: Verify that SSH Server and SSH Client are configured securely
version: 1.0.0
supports:
- os-family: linux
depends:
- name: profile
path: ../path/to/profile
inspec_version: "~> 2.1"
```YAML
name: ssh
title: Basic SSH
maintainer: Chef Software, Inc.
copyright: Chef Software, Inc.
copyright_email: support@chef.io
license: Proprietary, All rights reserved
summary: Verify that SSH Server and SSH Client are configured securely
version: 1.0.0
supports:
- os-family: linux
depends:
- name: profile
path: ../path/to/profile
inspec_version: "~> 2.1"
```
## Verify Profiles
Use the `inspec check` command to verify the implementation of a profile:
$ inspec check examples/profile
```bash
$ inspec check examples/profile
```
# Platform Support
Use the `supports` setting in the `inspec.yml` file to specify one (or more) platforms for which a profile is targeting. The list of supported platforms may contain simple names, names and versions, or detailed flags, and may be combined arbitrarily. For example, to target anything running Debian Linux:
name: ssh
supports:
- os-name: debian
```YAML
name: ssh
supports:
- os-name: debian
```
and to target only Ubuntu version 14.04
name: ssh
supports:
- os-name: ubuntu
release: 14.04
```YAML
name: ssh
supports:
- os-name: ubuntu
release: 14.04
```
and to target the entire RedHat platform (including CentOS and Oracle Linux):
name: ssh
supports:
- os-family: redhat
```YAML
name: ssh
supports:
- os-family: redhat
```
and to target anything running on Amazon AWS:
name: ssh
supports:
- platform: aws
```YAML
name: ssh
supports:
- platform: aws
```
and to target all of these examples in a single `inspec.yml` file:
name: ssh
supports:
- os-name: debian
- os-name: ubuntu
release: 14.04
- os-family: redhat
- platform: aws
```YAML
name: ssh
supports:
- os-name: debian
- os-name: ubuntu
release: 14.04
- os-family: redhat
- platform: aws
```
# Profile Dependencies
@ -121,11 +136,13 @@ For hands-on examples, check out [Create a custom InSpec profile](https://learn.
Before a profile can use controls from another profile, the to-be-included profile needs to be specified in the including profiles `inspec.yml` file in the `depends` section. For each profile to be included, a location for the profile from where to be fetched and a name for the profile should be included. For example:
depends:
- name: linux-baseline
url: https://github.com/dev-sec/linux-baseline/archive/master.tar.gz
- name: ssh-baseline
url: https://github.com/dev-sec/ssh-baseline/archive/master.tar.gz
```YAML
depends:
- name: linux-baseline
url: https://github.com/dev-sec/linux-baseline/archive/master.tar.gz
- name: ssh-baseline
url: https://github.com/dev-sec/ssh-baseline/archive/master.tar.gz
```
InSpec supports a number of dependency sources.
@ -133,21 +150,25 @@ InSpec supports a number of dependency sources.
The `path` setting defines a profile that is located on disk. This setting is typically used during development of profiles and when debugging profiles.
depends:
- name: my-profile
path: /absolute/path
- name: another
path: ../relative/path
```YAML
depends:
- name: my-profile
path: /absolute/path
- name: another
path: ../relative/path
```
### url
The `url` setting specifies a profile that is located at an HTTP- or HTTPS-based URL. The profile must be accessible via a HTTP GET operation and must be a valid profile archive (zip, tar, or tar.gz format).
depends:
- name: my-profile
url: https://my.domain/path/to/profile.tgz
- name: profile-via-git
url: https://github.com/myusername/myprofile-repo/archive/master.tar.gz
```YAML
depends:
- name: my-profile
url: https://my.domain/path/to/profile.tgz
- name: profile-via-git
url: https://github.com/myusername/myprofile-repo/archive/master.tar.gz
```
### git
@ -155,13 +176,15 @@ A `git` setting specifies a profile that is located in a git repository, with op
For example:
depends:
- name: git-profile
git: http://url/to/repo
branch: desired_branch
tag: desired_version
commit: pinned_commit
version: semver_via_tags
```YAML
depends:
- name: git-profile
git: http://url/to/repo
branch: desired_branch
tag: desired_version
commit: pinned_commit
version: semver_via_tags
```
### supermarket
@ -169,9 +192,11 @@ A `supermarket` setting specifies a profile that is located in a cookbook hosted
For example:
depends:
- name: supermarket-profile
supermarket: supermarket-username/supermarket-profile
```YAML
depends:
- name: supermarket-profile
supermarket: supermarket-username/supermarket-profile
```
Available Supermarket profiles can be listed with `inspec supermarket profiles`.
@ -181,9 +206,11 @@ A `compliance` setting specifies a profile that is located on the Chef Automate
For example:
depends:
- name: linux
compliance: base/linux
```YAML
depends:
- name: linux
compliance: base/linux
```
## Vendoring Dependencies
@ -199,15 +226,17 @@ Once defined in the `inspec.yml`, controls from the included profiles can be use
With the `include_controls` command in a profile, all controls from the named profile will be executed every time the including profile is executed.
```YAML
![Include Controls](/images/profile_inheritance/include_controls.png)
```
In the example above, every time `my-app-profile` is executed, all the controls from `my-baseline` are also executed. Therefore, the following controls would be executed:
* myapp-1
* myapp-2
* myapp-3
* baseline-1
* baseline-2
* myapp-1
* myapp-2
* myapp-3
* baseline-1
* baseline-2
This is a great reminder that having a good naming convention for your controls is helpful to avoid confusion when
including controls from other profiles!
@ -216,7 +245,9 @@ including controls from other profiles!
What if one of the controls from the included profile does not apply to your environment? Luckily, it is not necessary to maintain a slightly-modified copy of the included profile just to delete a control. The `skip_control` command tells InSpec to not run a particular control.
```YAML
![Include Controls with Skip](/images/profile_inheritance/include_controls_with_skip.png)
```
In the above example, all controls from `my-app-profile` and `my-baseline` profile will be executed every time `my-app-profile` is executed **except** for control `baseline-2` from the `my-baseline` profile.
@ -226,7 +257,9 @@ Let's say a particular control from an included profile should still be run, but
When a control is included, it can also be modified!
```YAML
![Include Controls with Modification](/images/profile_inheritance/include_controls_with_mod.png)
```
In the above example, all controls from `my-baseline` are executed along with all the controls from the including profile, `my-app-profile`. However, should control `baseline-1` fail, it will be raised with an impact of `0.5` instead of the originally-intended impact of `1.0`.
@ -234,21 +267,25 @@ In the above example, all controls from `my-baseline` are executed along with al
If there are only a handful of controls that should be executed from an included profile, it's not necessarily to skip all the unneeded controls, or worse, copy/paste those controls bit-for-bit into your profile. Instead, use the `require_controls` command.
```YAML
![Require Controls](/images/profile_inheritance/require_controls.png)
```
Whenever `my-app-profile` is executed, in addition to its own controls, it will run only the controls specified in the `require_controls` block. In the case, the following controls would be executed:
* myapp-1
* myapp-2
* myapp-3
* baseline-2
* baseline-4
* myapp-1
* myapp-2
* myapp-3
* baseline-2
* baseline-4
Controls `baseline-1`, `baseline-3`, and `baseline-5` would not be run, just as if they were manually skipped. This method of including specific controls ensures only the controls specified are executed; if new controls are added to a later version of `my-baseline`, they would not be run.
And, just the way its possible to modify controls when using `include_controls`, controls can be modified as well.
```YAML
![Require Controls with Modification](/images/profile_inheritance/require_controls_with_mod.png)
```
As with the prior example, only `baseline-2` and `baseline-4` are executed, but if `baseline-2` fails, it will report with an impact of `0.5` instead of the originally-intended `1.0` impact.
@ -259,46 +296,54 @@ for use in your profile. If two of your dependencies provide a resource with
the same name, you can use the `require_resource` DSL function to
disambiguate the two:
require_resource(profile: 'my_dep', resource: 'my_res',
as: 'my_res2')
```YAML
require_resource(profile: 'my_dep', resource: 'my_res',
as: 'my_res2')
```
This will allow you to reference the resource `my_res` from the
profile `my_dep` using the name `my_res2`.
# Profile Attributes
Attributes may be used in profiles to define secrets, such as user names and passwords, that should not otherwise be stored in plain-text in a cookbook. First specify a variable in the control for each secret, then add the secret to a Yaml file located on the local machine, and then run `inspec exec` and specify the path to that Yaml file using the `--attrs` attribute.
Attributes may be used in profiles to define secrets, such as user names and passwords, that should not otherwise be stored in plain-text in a cookbook. First specify a variable in the control for each secret, then add the secret to a YAML file located on the local machine, and then run `inspec exec` and specify the path to that Yaml file using the `--attrs` attribute.
For example, a control:
# define these attributes on the top-level of your file and re-use them across all tests!
val_user = attribute('user', default: 'alice', description: 'An identification for the user')
val_password = attribute('password', description: 'A value for the password')
```Ruby
# define these attributes on the top-level of your file and re-use them across all tests!
val_user = attribute('user', default: 'alice', description: 'An identification for the user')
val_password = attribute('password', description: 'A value for the password')
control 'system-users' do
impact 0.8
desc '
This test assures that the user "Bob" has a user installed on the system, along with a
specified password.
'
control 'system-users' do
impact 0.8
desc '
This test assures that the user "Bob" has a user installed on the system, along with a
specified password.
'
describe val_user do
it { should eq 'bob' }
end
val_user do
it { should eq 'bob' }
end
describe val_password do
it { should eq 'secret' }
end
end
describe val_password do
it { should eq 'secret' }
end
end
```
And a Yaml file named `profile-attribute.yml`:
And a YAML file named `profile-attribute.yml`:
user: bob
password: secret
```YAML
user: bob
password: secret
```
The following command runs the tests and applies the secrets specified in `profile-attribute.yml`:
$ inspec exec examples/profile-attribute --attrs examples/profile-attribute.yml
```bash
$ inspec exec examples/profile-attribute --attrs examples/profile-attribute.yml
```
See the full example in the InSpec open source repository: [Example InSpec Profile with Attributes](https://github.com/chef/inspec/tree/master/examples/profile-attribute)
@ -310,33 +355,39 @@ To access these files, they must be stored in the `files` directory at the root
Here is an example for reading and testing a list of ports. The folder structure is:
examples/profile
├── controls
│ ├── example.rb
|── files
│ └── services.yml
└── inspec.yml
```YAML
examples/profile
├── controls
│ ├── example.rb
│── files
│ └── services.yml
└── inspec.yml
```
With `services.yml` containing:
- service_name: httpd-alpha
port: 80
- service_name: httpd-beta
port: 8080
```YAML
- service_name: httpd-alpha
port: 80
- service_name: httpd-beta
port: 8080
```
The tests in `example.rb` can now access this file:
my_services = yaml(content: inspec.profile.file('services.yml')).params
```Ruby
my_services = yaml(content: inspec.profile.file('services.yml')).params
my_services.each do |s|
describe service(s['service_name']) do
it { should be_running }
end
my_services.each do |s|
describe service(s['service_name']) do
it { should be_running }
end
describe port(s['port']) do
it { should be_listening }
end
end
describe port(s['port']) do
it { should be_listening }
end
end
```
For a more complete example that uses a profile file, see [Explore InSpec resources](https://learn.chef.io/modules/explore-inspec-resources#/) on Learn Chef Rally.
@ -346,33 +397,43 @@ Users familiar with the RSpec testing framework may know that there are two ways
InSpec will continue to support both methods of writing tests. Consider this `file` test:
describe file('/tmp/test.txt') do
it { should be_file }
end
```Ruby
describe file('/tmp/test.txt') do
it { should be_file }
end
```
This can be re-written with `expect` syntax
describe file('/tmp/test.txt') do
it 'should be a file' do
expect(subject).to(be_file)
end
end
```Ruby
describe file('/tmp/test.txt') do
it 'should be a file' do
expect(subject).to(be_file)
end
end
```
The output of both of the above examples looks like this:
File /tmp/test.txt
✔ should be a file
```text
File /tmp/test.txt
✔ should be a file
```
In addition, you can make use of the `subject` keyword to further control your output if you choose:
describe 'test file' do
subject { file('/tmp/test.txt') }
it 'should be a file' do
expect(subject).to(be_file)
end
end
```Ruby
describe 'test file' do
subject { file('/tmp/test.txt') }
it 'should be a file' do
expect(subject).to(be_file)
end
end
```
... which will render the following output:
test file
✔ should be a file
```text
test file
✔ should be a file
```

View file

@ -116,12 +116,12 @@ This reporter includes all information from the rspec runner. Unlike the json re
This renders html code to view your tests in a browser. It includes all the test and summary information.
## Automate Reporter
The automate reporter type is a special reporter used with the Automate 2 suite. To use this reporter you must pass in the correct configuration via a json config `--json-config`.
Example config:
```json
"reporter": {
"automate" : {
@ -135,27 +135,36 @@ Example config:
}
```
### Mandatory fields:
### Mandatory fields
#### stdout
This will either suppress or show the automate report in the CLI screen on completion
#### url
This is your Automate 2 url. Append `data-collector/v0/` at the end.
#### token
This is your Automate 2 token. You can generate this token by navigating to the admin tab of A2 and then api keys.
### Optional fields
#### insecure
This will disable or enable the ssl check when accessing the Automate 2 instance.
PLEASE NOTE: These fields are ONLY needed if you do not have chef-client attached to a chef server running on your node. The fields below will be automaticlly pulled from the chef server.
PLEASE NOTE: These fields are ONLY needed if you do not have chef-client attached to a chef server running on your node. The fields below will be automatically pulled from the chef server.
#### node_name
This will be the node name which shows up in Automate 2.
#### node_uuid
This overrides the node uuid sent up to Automate 2. On non-chef nodes we will try to generate a static node uuid for you from your hardware. This will almost never be needed unless your working with a unique virtual setup.
#### environment
This will set the enviroment metadata for Automate 2.
This will set the environment metadata for Automate 2.

View file

@ -61,7 +61,6 @@ to process the output of `ls` executed on the target system, use
Similarly, use `inspec.file(PATH)` to access files or directories from
remote systems in your tests or custom resources.
## Using rubygems
Ruby gems are self-contained programs and libraries. If you create a custom
@ -158,7 +157,8 @@ When writing tests you can not use standard ruby methods to shellout as it tries
However, the `command` resource has a `.stdout` method that will allow you to manipulate the results.
Using the above example, you could check the writes on several subdirectories.
### Example 1:
### Example 1
```ruby
$ inspec shell
Welcome to the interactive InSpec Shell
@ -179,7 +179,8 @@ Version: (not specified)
Test Summary: 1 successful, 0 failures, 0 skipped
```
### Example 2:
### Example 2
```ruby
$ inspec shell
Welcome to the interactive InSpec Shell