inspec 2.2.16 → 2.2.20

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d449eb17f22c3c36f906fc5ed5be7541e281aef888d6c1bd4e2db3058282afc2
4
- data.tar.gz: f9a50c6499b0682106a4d3b05ab8776032671b0f04e01323e20f0812d9ae8857
3
+ metadata.gz: e42bda28814bf570413a78722e5d9b8533e3e993ba01aacea19822b4bd2a8fb5
4
+ data.tar.gz: d4c231e279a19a1875aaa21d1eb82cc507c942f4bd82051146f52b61fd9331ff
5
5
  SHA512:
6
- metadata.gz: 13e3b372d12dcbce84246f2bcdebaaf9fd2938093b1c75d1913e095031b1243b37cc869c82d71a826a47b8aa154b9ac9a1da96bf7f3d394a58943361ad8b6419
7
- data.tar.gz: a3ddf1079f27dc2ba750893d6472d8c2aba7d77c48a7dde980968cd0634dd78b0c55df4f728ab704f916beb9a3bac3f289a8dec10fe5b0733663664859bbffb9
6
+ metadata.gz: bbe7929ee06d7a836d46e2d661048631b5bb32e2214ce13c67a6a3cfa2efb51db9469e3832d90de76d87193bcf70c29a9379c3ef8a4b95d0c8ad241ef3396e4f
7
+ data.tar.gz: 432df70f939256dbd22e5f8e8a8399030650c0bd9ee042eb4d89370ea151e17cafff810b012afba07ddb67b35c7bad4999067a496afcfc944593c1520c0095f5
data/CHANGELOG.md CHANGED
@@ -1,27 +1,38 @@
1
1
  # Change Log
2
2
  <!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ -->
3
- <!-- latest_release 2.2.16 -->
4
- ## [v2.2.16](https://github.com/inspec/inspec/tree/v2.2.16) (2018-06-15)
3
+ <!-- latest_release 2.2.20 -->
4
+ ## [v2.2.20](https://github.com/inspec/inspec/tree/v2.2.20) (2018-06-21)
5
5
 
6
6
  #### Merged Pull Requests
7
- - deprecate azure_generic_resource [#3132](https://github.com/inspec/inspec/pull/3132) ([chris-rock](https://github.com/chris-rock))
7
+ - Accept symbols and downcased criteria in aws_iam_policy have_statement matcher [#3129](https://github.com/inspec/inspec/pull/3129) ([clintoncwolfe](https://github.com/clintoncwolfe))
8
8
  <!-- latest_release -->
9
9
 
10
- <!-- release_rollup since=2.2.10 -->
11
- ### Changes since 2.2.10 release
12
-
13
- #### Enhancements
14
- - Fix unit tests for ruby 2.5 [#3125](https://github.com/inspec/inspec/pull/3125) ([jquick](https://github.com/jquick)) <!-- 2.2.12 -->
10
+ <!-- release_rollup since=2.2.16 -->
11
+ ### Changes since 2.2.16 release
15
12
 
16
13
  #### Merged Pull Requests
17
- - deprecate azure_generic_resource [#3132](https://github.com/inspec/inspec/pull/3132) ([chris-rock](https://github.com/chris-rock)) <!-- 2.2.16 -->
18
- - Bump train version for inspec [#3147](https://github.com/inspec/inspec/pull/3147) ([jquick](https://github.com/jquick)) <!-- 2.2.15 -->
19
- - Add insecure option to the automate report json [#3124](https://github.com/inspec/inspec/pull/3124) ([jquick](https://github.com/jquick)) <!-- 2.2.14 -->
20
- - Add list properties back to shadow [#3140](https://github.com/inspec/inspec/pull/3140) ([clintoncwolfe](https://github.com/clintoncwolfe)) <!-- 2.2.13 -->
21
- - Translate `auditd -s` RHEL output to match CentOS [#3114](https://github.com/inspec/inspec/pull/3114) ([jerryaldrichiii](https://github.com/jerryaldrichiii)) <!-- 2.2.11 -->
14
+ - Accept symbols and downcased criteria in aws_iam_policy have_statement matcher [#3129](https://github.com/inspec/inspec/pull/3129) ([clintoncwolfe](https://github.com/clintoncwolfe)) <!-- 2.2.20 -->
15
+
16
+ #### Enhancements
17
+ - Fix control merging when overriding child controls [#3155](https://github.com/inspec/inspec/pull/3155) ([jquick](https://github.com/jquick)) <!-- 2.2.19 -->
18
+ - auditd resource: Add handling for sudo/no command [#3151](https://github.com/inspec/inspec/pull/3151) ([jerryaldrichiii](https://github.com/jerryaldrichiii)) <!-- 2.2.18 -->
19
+ - updated skip message to reflect accurate version of audit support [#3153](https://github.com/inspec/inspec/pull/3153) ([jeremymv2](https://github.com/jeremymv2)) <!-- 2.2.17 -->
22
20
  <!-- release_rollup -->
23
21
 
24
22
  <!-- latest_stable_release -->
23
+ ## [v2.2.16](https://github.com/inspec/inspec/tree/v2.2.16) (2018-06-15)
24
+
25
+ #### Enhancements
26
+ - Fix unit tests for ruby 2.5 [#3125](https://github.com/inspec/inspec/pull/3125) ([jquick](https://github.com/jquick))
27
+
28
+ #### Merged Pull Requests
29
+ - Translate `auditd -s` RHEL output to match CentOS [#3114](https://github.com/inspec/inspec/pull/3114) ([jerryaldrichiii](https://github.com/jerryaldrichiii))
30
+ - Add list properties back to shadow [#3140](https://github.com/inspec/inspec/pull/3140) ([clintoncwolfe](https://github.com/clintoncwolfe))
31
+ - Add insecure option to the automate report json [#3124](https://github.com/inspec/inspec/pull/3124) ([jquick](https://github.com/jquick))
32
+ - Bump train version for inspec [#3147](https://github.com/inspec/inspec/pull/3147) ([jquick](https://github.com/jquick))
33
+ - deprecate azure_generic_resource [#3132](https://github.com/inspec/inspec/pull/3132) ([chris-rock](https://github.com/chris-rock))
34
+ <!-- latest_stable_release -->
35
+
25
36
  ## [v2.2.10](https://github.com/inspec/inspec/tree/v2.2.10) (2018-06-08)
26
37
 
27
38
  #### New Resources
@@ -44,7 +55,6 @@
44
55
  - Add lazy-loading to FilterTable [#3093](https://github.com/inspec/inspec/pull/3093) ([clintoncwolfe](https://github.com/clintoncwolfe))
45
56
  - Update Junit.rb to add failures attribute [#3086](https://github.com/inspec/inspec/pull/3086) ([scboucher](https://github.com/scboucher))
46
57
  - Clean up issues in documentation [#3058](https://github.com/inspec/inspec/pull/3058) ([miah](https://github.com/miah))
47
- <!-- latest_stable_release -->
48
58
 
49
59
  ## [v2.1.84](https://github.com/inspec/inspec/tree/v2.1.84) (2018-05-31)
50
60
 
data/docs/glossary.md CHANGED
@@ -1,99 +1,381 @@
1
1
  # InSpec Glossary
2
2
 
3
- ## Basic Syntax
3
+ This document should help you become familiar with some of the terminology used by the InSpec project.
4
+
5
+ There are two ways to use it:
6
+
7
+ * A [text glossary](#text_glossary). Learn the meaning of a word you have encountered.
8
+ * A [visual glossary](#visual_glossary). Look at examples and see how the parts are labelled. You can then use the text glossary to read details of each concept.
9
+
10
+ ## Visual Glossary
11
+
12
+ ### Motivating Example
13
+
14
+ 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.
15
+
16
+ ### Basic Syntax
17
+
18
+ Let's look at some simple examples.
19
+
20
+ ### Singular Resource Example
21
+
22
+ ```inspec
23
+ describe car(owner: 'Tony Clifton') do
24
+ it { should exist }
25
+ its('license_plate') { should cmp 'MOONMAN' }
26
+ it { should be_classy }
27
+ it { should_not have_check_engine_light_on }
28
+ end
4
29
  ```
5
- describe foo('/path/to/foo.txt') do
6
- its('blah') { should cmp '123' }
30
+
31
+ #### describe car(owner: 'Tony Clifton') do
32
+
33
+ _car_ is a [resource](#resource). Since we are talking about only one car, it is a [singular resource](#singular_resource).
34
+
35
+ #### describe car(_owner: 'Tony Clifton'_)
36
+
37
+ _owner_ is a [resource parameter](#resource_parameter) and _'Tony Clifton'_ is a resource parameter value.
38
+
39
+ #### _it { should exist }_
40
+
41
+ Each line within the resource block beginning with `it` or `its` is a [test](#test). Use [it](#it) to access [resource-specific matchers](#resource_specific_matcher), and use [its](#its) to access [properties](#property) of the [resource](#resource), which are in turn used with [universal matchers](#universal_matcher).
42
+
43
+ #### its('_license\_plate_') { should cmp 'MOONMAN' }
44
+
45
+ _license\_plate_ is a [property](#property) belonging to the [resource](#resource). Properties expose testable information about the resource. Some properties are numbers, some (like this one) are text, some are lists, and some are more complex objects. Properties are always used with [universal matchers](#universal_matcher).
46
+
47
+ #### its('license\_plate') { should _cmp_ 'MOONMAN' }
48
+
49
+ _cmp_ is a [universal matcher](#universal_matcher). `cmp` is a very flexible, loosely typed equality operator; here it checks to see if the license plate text is the same as the text 'MOONMAN'. Notice that the test operates on the license plate text (the property value) and not on the resource. You can find the full list of supported universal matchers on the [Universal Matcher page](https://www.inspec.io/docs/reference/matchers/).
50
+
51
+ #### its('license\_plate') { should cmp _'MOONMAN'_ }
52
+
53
+ _'MOONMAN'_ is an [expected result](#expected_result). Some matchers take an expected result; others do not.
54
+
55
+ #### it { should _be\_classy_ }
56
+
57
+ _be\_classy_ is a [resource-specific matcher](#resource_specific_matcher). It returns a yes-or-no value, based on whether Tony's car is classy or not. (It is. Tony is a classy guy.)
58
+
59
+ #### it { _should\_not_ have\_check\_engine\_light\_on }
60
+
61
+ _should\_not_ indicates this is a negated test. So, this test passes if the matcher says "no".
62
+
63
+ ### Plural Resource Example
64
+
65
+ ```inspec
66
+ describe cars.where(color: /^b/) do
7
67
  it { should exist }
8
- it { should be_reasonable }
9
- it { should_not be_ridiculous }
68
+ its('manufacturers') { should include 'Cadillac' }
69
+ its('count') { should be >= 10 }
70
+ end
71
+ ```
72
+
73
+ #### describe _cars_.where(color: /^b/) do
74
+
75
+ _cars_ is a [resource](#resource). Since we are potentially talking about many cars, it is a [plural resource](#plural_resource).
76
+
77
+ #### describe cars._where(color: /^b/)_ do
78
+
79
+ _where(color: /^b/)_ is a [filter statement](#filter_statement). Without a filter statement, `cars` simply selects all the cars in the world.
80
+
81
+ #### describe cars.where(_color: /^b/_) do
82
+
83
+ _color_ is a [filter criterion](#filter_criteria) along with its filter value, _/^b/_. Here, the criterion expresses that we want to select all cars whose colors begin with the letter 'b' - blue, brown, burgundy, etc.
84
+
85
+ #### _it { should exist }_
86
+
87
+ Each line within the resource block beginning with `it` or `its` is a [test](#test). Use [it](#it) to access [resource-specific matchers](#resource_specific_matcher), and use [its](#its) to access [properties](#property) of the [resource](#resource), which are in turn used with [universal matchers](#universal_matcher).
88
+
89
+ With plural resources, `exist` has a special meaning: did the filter match anything?
90
+
91
+ #### its('_manufacturers_') { should include 'Cadillac' }
92
+
93
+ _manufacturers_ is a [property](#property) of the [resource](#resource). Properties expose testable information about the resource. On plural resources, properties are almost always names in the plural, and almost always return a list of values. Here, the test returns a list of the car manufacturer names. Some list properties are de-duplicated; for example, you might have 10 cars, but if they are all Subarus and Cadillacs, it returns only two entries in the `manufacturers` property. Be sure to check the documentation for your resource.
94
+
95
+ #### its('manufacturers') { should _include_ 'Cadillac' }
96
+
97
+ _include_ is a [universal matcher](#universal_matcher). `include` works with lists, and checks to see if an expected result is present. Here, it checks to see if the list of manufacturers contains an entry with the text 'Cadillac'. Notice it operates on the manufacturers list (the property value) and not on the resource. You can find the full list of supported universal matchers on the [Universal Matcher page](https://www.inspec.io/docs/reference/matchers/).
98
+
99
+ #### its('manufacturers') { should include '_Cadillac_' }
100
+
101
+ _'Cadillac'_ is an [expected result](#expected_result). Some matchers take an expected result; others do not.
102
+
103
+ #### its('count') { should _be >=_ 10 }
104
+
105
+ _be >=_ is an [operator matcher](#operator matcher). It allows you to perform numeric comparisons. All plural resources have a `count` property.
106
+
107
+ ## Text Glossary
108
+
109
+ ### attribute
110
+
111
+ An _attribute_ is a parameter that InSpec reads from a YAML file provided on the command line. You can use this feature either to change a [profile's](#profile) behavior by passing different attribute files or to store secrets that should not be directly present in a profile. InSpec attributes are unrelated to Chef attributes.
112
+
113
+ The CLI syntax for attributes is documented under the [`inspec exec`](https://www.inspec.io/docs/reference/cli/#exec) command.
114
+
115
+ The syntax for accessing attributes within a profile is documented in the [profiles documentation](https://www.inspec.io/docs/reference/profiles/#profile-attributes).
116
+
117
+ ### control
118
+
119
+ ### control block
120
+
121
+ The _`control`_ keyword is used to declare a _`control block`_. Here, the word 'control' means a 'regulatory control, recommendation, or requirement' - not a software engineering construct. A `control block` has a name (which usually refers to the assigned ID of the regulatory recommendation it implements), metadata such as descriptions, references, and tags, and finally groups together related [describe blocks](#describe_block) to implement the checks.
122
+
123
+ ### core resource
124
+
125
+ A [resource](#resource) that is included with InSpec; you are not required to install additional [plugins](#plugin) or depend on a [resource pack](#resource pack) to use the resource.
126
+
127
+ ### custom resource
128
+
129
+ A [resource](#resource) that is _not_ included with InSpec. It may be a resource of your own creation, or one you obtain by depending on a [resource pack](#resource pack).
130
+
131
+ ### describe
132
+
133
+ ### describe block
134
+
135
+ 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.
136
+
137
+ ```
138
+ control 'Rule 1.1 - Color restrictions' do
139
+ # Count only blue cars
140
+ describe cars.where(color: 'blue') do
141
+ its('count') { should eq 20 }
142
+ end
10
143
  end
11
144
  ```
12
- ## Basic Elements:
13
145
 
14
- ### describe **foo**, where
146
+ ### DSL
15
147
 
16
- * `foo` is the _resource_
148
+ _DSL_ is an acronym for _Domain Specific Language_. It refers to the language extensions InSpec provides to make authoring resources and controls easier. While InSpec control files are use Ruby, the _Control DSL_ makes it easy to write controls without knowledge of Ruby by providing DSL keywords such as [describe](#describe), [control](#control), [it](#it) and [its](#its). See the [InSpec DSL page](https://www.inspec.io/docs/reference/dsl_inspec/) for details about keywords available to control authors.
17
149
 
18
- ### describe foo **('/path/to/foo.txt')**, where
150
+ For [custom resource](#custom_resource) authors, an additional DSL is available - see the [Resource DSL page](https://www.inspec.io/docs/reference/dsl_resource/).
19
151
 
20
- * `'/path/to/foo.txt'` is the _resource parameter_
152
+ ### expected result
21
153
 
22
- ## Tests:
154
+ When using a [matcher](#matcher), the _`expected result`_ is the value the matcher will compare against the [property](#property) being accessed.
23
155
 
24
- ### **its('blah') { should cmp '123' }** is an _individual test_, where
156
+ 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'.
25
157
 
26
- * `blah` is a _property_
27
- * { should cmp '123' } is a _condition statement_
28
- * `should` is the _condition_
29
- * `cmp` is the _matcher_
30
- * `'123'` is the _expected result_
158
+ ```
159
+ describe car(owner: 'Bruce Wayne') do
160
+ its('color') { should cmp 'black' }
161
+ end
162
+ ```
31
163
 
32
- ### **{ should exist }** is a _condition statement_, where
164
+ ### filter statement
33
165
 
34
- * `should` is the _condition_
35
- * `exist` is the _matcher_
166
+ When using a [plural resource](#plural_resource), a _`filter statement`_ is used to select individual test subjects using [filter criteria](#filter_criteria). A filter statement almost always is indicated by the keyword `where`, and may be repeated using method chaining.
36
167
 
37
- ### **{ should be\_reasonable }** is a _condition statement_, where
38
-
39
- * `should` is the _condition_
40
- * `be_reasonable` is the _matcher_
168
+ A filter statement may use method call syntax (which allows basic criteria operations, such as equality, regex matching, and ruby `===` comparison) or block syntax (which allows arbitrary code).
41
169
 
42
- ### **{ should\_not be\_ridiculous }** is a _negative condition statement_, where
170
+ In this example, `where(...)` is the filter statement.
43
171
 
44
- * `should_not` is the _negative condition_
45
- * `be_ridiculous` is the _matcher_
172
+ ```
173
+ # Count only blue cars
174
+ describe cars.where(color: 'blue') do
175
+ its('count') { should eq 20 }
176
+ end
177
+ ```
178
+
179
+ ### filter criterion
180
+
181
+ ### filter criteria
182
+
183
+ When using a [plural resource](#plural_resource), a _`filter criterion`_ is used to select individual test subjects within a [filter statement](#filter_statement). You may use multiple _`filter criteria`_ in a single filter statement.
184
+
185
+ When method-call syntax is used with the filter statement, you provide filter criteria as a Hash, with filter criteria names as keys, and conditions as the Hash values. You may provide test, true/false, or numbers, in which case the comparison is equality; or you may provide a regular expression, in which case a match is performed.
46
186
 
47
- ## Advanced Syntax
187
+ Here, `(color: blue)` is a single filter criterion being used with a filter statement in method-call syntax.
48
188
 
49
189
  ```
50
- describe foos('/path/to/foo.txt', ssl_verify: true).where { names == 'blah' } do
51
- its('jared') { should cmp >= 123 }
52
- its('jared.sort.first.monkey') { should be `loud` }
53
- its(['jared', 'monkey.with.dots']) { should be `loud` }
190
+ # Count only blue cars
191
+ describe cars.where(color: 'blue') do
192
+ its('count') { should eq 20 }
54
193
  end
55
194
  ```
56
195
 
57
- ## Advanced Elements:
196
+ When block-method syntax is used with the filter statement, you provide a block. The block may contain arbitrary code, and each filter criteria will be available as an accessor. The block will be evaluated once per row, and each block that evaluates to a truthy value will pass the filter.
58
197
 
59
- ### describe **foos**, where
198
+ Here, `{ engine_cylinders >= 6 }` is a block-syntax filter statement referring to one filter criterion.
60
199
 
61
- * `foos` is a _plural resource_
200
+ ```
201
+ # Vroom!
202
+ describe cars.where { engine_cylinders >= 6 } do
203
+ its('city_mpg_ratings') { should_not include '4-star' }
204
+ end
205
+ ```
62
206
 
63
- ### describe foos **('/path/to/foo.txt', ssl_verify: true)**, where
207
+ ### it
64
208
 
65
- * `'/path/to/foo.txt'` and `ssl_verify: true` are the _resource parameters_. Resources take one or more parameters.
209
+ Within a [describe block](#describe), _`it`_ declares an individual [test](#test) directly against the [resource](#resource) (as opposed to testing against one of the resource's [properties](#property), as [its](#its) does). Though it is possible to use [universal matchers](#universal_matcher) with `it`, it is much more typical to use [resource-specific matchers](#resource_specific_matchers).
66
210
 
67
- ## Filters:
211
+ `it` may be used with `should`, or negated using `should_not`.
68
212
 
69
- ### describe foos ('/path/to/foo.txt', ssl_verify: true)**.where { names == 'blah' }**
213
+ Here, `it { should ... }` declares a test, calling the `classy?` matcher on Tony Clifton's car.
70
214
 
71
- * `.where { names == 'blah' }` is an example of a **filter**.
72
- * `{ names == 'blah' }` is an example of a _filter clause_
73
- * Some resources support one or more filters.
74
- * Filters are used on plural resources.
75
- * Some resources, such as `etc_hosts` are explicitly plural, while others, such as `passwd` are implicitly plural.
215
+ ```
216
+ describe car(owner: 'Tony Clifton') do
217
+ it { should be_classy }
218
+ end
219
+ ```
220
+
221
+ ### its
222
+
223
+ Within a [describe block](#describe), _`its`_ declares an individual [test](#test) against a property of the [resource](#resource) (as opposed to testing directly against the resource itself, as [it](#it) does). You must use [universal matchers](#universal_matcher) with `its`; you cannot use [resource-specific matchers](#resource_specific_matchers).
224
+
225
+ `its` may be used with `should`, or negated using `should_not`.
226
+
227
+ The property to access is passed as a single string argument to `its`. As an advanced usage, if the property has methods you are interested in, you can call them using '`.`' within the string; even more advanced calling patterns are possible - see [the rspec-its documentation](https://github.com/rspec/rspec-its#usage).
228
+
229
+ 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.
230
+
231
+ ```
232
+ describe car(owner: 'Tony Clifton') do
233
+ its('fuzzy_dice') { should_not be_empty }
234
+ its('fuzzy_dice.count') { should be >= 2 }
235
+ its('fuzzy_dice.first.fuzziness') { should cmp 'outlandishly so' }
236
+ end
237
+ ```
238
+
239
+ ### matcher
240
+
241
+ A _`matcher`_ performs the actual assertions against [resources](#resource) or the [properties](#property) of resources. Matchers always return a true/false value. Matchers fall into two camps:
242
+
243
+ * [resource-specific matchers](#resource_specific_matchers), which operate directly on the resource, are used with [it](#it), and tend to be highly customized to the auditing needs of the resource
244
+ * [universal matchers](#universal_matchers), which operate on the properties of the resource, are used with [its](#its), and tend to be very generic, operating on text, numbers, and lists
245
+
246
+ Some matchers accept parameters, called [expected results](#expected_results).
76
247
 
77
- ### **{ names == 'my-name' && spots == true }** are filter criteria
248
+ For information on how RSpec matchers are related o InSpec matchers, see [InSpec and RSpec](https://www.inspec.io/docs/reference/inspec_and_friends/#rspec).
249
+
250
+ Here, `be_classy` is a resource-specific matcher operating directly on the `car`, while `cmp` is a universal matcher operating on the `manufacturer` property.
251
+
252
+ ```
253
+ describe car(owner: 'Tony Clifton') do
254
+ it { should be_classy }
255
+ its('manufacturer') { should cmp 'Cadillac' }
256
+ end
257
+ ```
78
258
 
79
- * `names` compares output to `blah`
80
- * `has spots` evaluates to `true` or `false`
259
+ ### plural resource
81
260
 
82
- ## Properties:
261
+ A _`plural resource`_ is a [resource](#resource) that specializes in performing searches and represents multiple occurrences of the resource on the [target](#target) platform. Plural resources are used to audit counts, inspect group properties, and have the unique ability to enforce negative tests ("nothing like this should exist") often required by compliance standards. Plural resources are not intended to perform in-depth auditing of an individual; use [singular resources](#singular_resource) for that.
83
262
 
84
- ### **its('jared') { should cmp >= 123 }**
263
+ Plural resources nearly always have a name that ends in 's': `processes`, `aws_security_groups`, `cars`. Plural resources generally do not have [resource-specific matchers](#resource_specific_matcher). If they have properties, they are almost always list properties, meaning that they return a list of values, which may or may not be de-duplicated.
85
264
 
86
- * `jared` is the _property_
87
-
88
- ### **{ should cmp >= 123 }** is a conditional statement that uses a matcher with an operator and expected value.
265
+ Plural resources support [filter statements](#filter_statement). See the [resource documentation](https://www.inspec.io/docs/reference/resources/) for details regarding which [filter criteria](#filter_criteria) are supported on each resource.
266
+
267
+ Here, `cars` is a plural resource.
268
+
269
+ ```
270
+ describe cars.where(color: 'blue') do
271
+ its('count') { should eq 20 }
272
+ its('license_plates') { should include 'AUTOAZUL' }
273
+
274
+ # License plates are unique, should have 20
275
+ its('license_plates.count') { should cmp 20 }
276
+
277
+ # Manufacturers are de-duplicated
278
+ its('manufacturers') { should include 'Subaru' }
279
+ its('manufacturers.count') { should be < 10 }
280
+ end
281
+ ```
282
+
283
+ ### profile
284
+
285
+ A _`profile`_ is a set of related [controls](#control) in a distributable form. You might have a locally-developed profile that your organization uses to define baseline security on all machines, or you might use a pre-defined profile that implements the requirements of a specific compliance standard. For full details about the capabilities of a profile, see the [profile documentation](https://www.inspec.io/docs/reference/profiles/).
286
+
287
+ Profiles may be distributed locally as a directory tree, as a tarball or zipfile at a URL, as a git repo, and several other ways. Profiles contain metadata, including versioning, and can setup dependency relationships with other profiles.
288
+
289
+ Aside from controls, profiles can also contain [custom resources](#custom_resource). If the profile contains only custom resources and no controls, we call it a [resource pack](#resource_pack).
290
+
291
+ ### property
292
+
293
+ A fact about a [resource](#resource). Typically, you use the [its](#its) keyword to access the property and write a [test](#test) within a [describe block](#describe_block), and then use a [universal matcher](#universal_matcher) to make assertions about the value of the property.
294
+
295
+ Each resource has different properties. See the [resource documentation](https://www.inspec.io/docs/reference/resources/) for details.
296
+
297
+ Here, `manufacturer` is a property of the `car` resource.
298
+
299
+ ```
300
+ describe car(owner: 'Tony Clifton') do
301
+ its('manufacturer') { should cmp 'Cadillac' }
302
+ end
303
+ ```
89
304
 
90
- * `cmp` is the _matcher_
91
- * `>=` is the operator (some matchers accept operators)
92
- * `123` is the expected value
305
+ ### reporter
93
306
 
94
- ## Properties with advanced usage:
307
+ An output format for the `inspec exec` command line. Several reporters are available, including JSON and JUnit; see the [inspec exec documentation](https://www.inspec.io/docs/reference/cli/#exec).
95
308
 
96
- ### Some properties may have advanced usage:
97
- #### **its `('jared.sort.first.monkey') { should be `loud` }`**
309
+ ### resource
98
310
 
99
- * `jared.sort.first.monkey` is an example of the `jared` property with an advanced usage
311
+ A _`resource`_ represents a category of things on the [target](#target) you wish to examine. For example, to check for the existence and permissions of a file, you would use the [`file`](https://www.inspec.io/docs/reference/resources/file/) resource. InSpec offers dozens of different resources, from the highly specialized (such as `aws_security_group`, which examines firewall rules in AWS) to the very general (such as `command`, which runs a command and lets you examine its output).
312
+
313
+ Resources are generally categorized as either [singular](#singular_resource) or [plural](#plural_resource), though there are some irregular resources that cannot be cleanly considered one or the other.
314
+
315
+ Resources are used within a [describe block](#describe_block) to perform [tests](#test).
316
+
317
+ Here, `car` is a resource.
318
+
319
+ ```
320
+ describe car(owner: 'Tony Clifton') do
321
+ it { should be_classy }
322
+ end
323
+ ```
324
+
325
+ ### resource pack
326
+
327
+ A _resource pack_ is a type of [profile](#profile) that is used to distribute [custom resources](#custom_resource). This specialized type of profile contains no [controls](#control), but it does contain a `libraries` directory within which Ruby files define custom resources.
328
+
329
+ ### resource parameter
330
+
331
+ _`resource parameters`_ are information passed to the resource when they are declared. Typically, resource parameters provide identifying information or connectivity information. Resource parameters are not the same as a [filter statement](#filter_statement).
332
+
333
+ Resource parameters vary from resource to resource; refer to the [resource documentation](https://www.inspec.io/docs/reference/resources/) for details.
334
+
335
+ Here, `owner: 'Tony Clifton'` is a resource parameter.
336
+
337
+ ```
338
+ describe car(owner: 'Tony Clifton') do
339
+ it { should be_classy }
340
+ end
341
+ ```
342
+
343
+ ### resource-specific matcher
344
+
345
+ A [matcher](#matcher) that operates directly on the [resource](#resource), as opposed to operating on a property as a [universal matcher](#universal matcher) does.
346
+
347
+ Resource-specific matchers often provide highly customized behavior. Check the [resource documentation](#https://www.inspec.io/docs/reference/resources/) to discover which resource-specific matchers are available for your resource.
348
+
349
+ For example, the hypothetical `car` resource defines a `classy?` method, which is exposed as the `be_classy` matcher in InSpec tests.
350
+
351
+ ```
352
+ describe car(owner: 'Tony Clifton') do
353
+ it { should be_classy }
354
+ end
355
+ ```
356
+
357
+ ### singular resource
358
+
359
+ A [resource](#resource) intended to uniquely identify a single object on the [target](#target). Singular resources specialize in providing richer auditing capabilities via resource-specific matchers. Compare to [plural resources](#plural_resource).
360
+
361
+ ### target
362
+
363
+ The _`target`_ is the OS or API on which InSpec is performing audits. In InSpec 1.x, this was always an operating system target (a bare metal machine, VM, or container). In InSpec 2.x and later, this can be an OS target, or an API target, including cloud providers such as AWS. InSpec is agentless, meaning that the InSpec code and profiles remain on your workstation, and the target is remotely interrogated without installing anything.
364
+
365
+ ### test
366
+
367
+ A _`test`_ is an individual assertion about the state of the [resource](#resource) or one of its [properties](#property). All tests begin with the keyword [it](#it) or [its](#its). Tests are grouped within a [describe block](#describe_block).
368
+
369
+ ### universal matcher
370
+
371
+ A _universal matcher_ is a [matcher](#matcher) that can be used on the [properties](#property) of any type of [resource](#resource). For example, you can use the `cmp` matcher to check the value of properties without having to worry about Ruby type-casting. Universal matchers are almost always used with the [its](#its) keyword.
372
+
373
+ Universal matchers are documented on the [Universal Matchers](https://www.inspec.io/docs/reference/matchers/) page.
374
+
375
+ Here, we access the 'color' property, then use the `cmp` universal matcher to compare the property to the 'black' [expected result](#expected_result).
376
+
377
+ ```
378
+ describe car(owner: 'Bruce Wayne') do
379
+ its('color') { should cmp 'black' }
380
+ end
381
+ ```
@@ -186,7 +186,7 @@ The test will pass if the identified policy attached the specified role.
186
186
 
187
187
  Examines the list of statements contained in the policy and passes if at least one of the statements matches. This matcher does _not_ interpret the policy in a request authorization context, as AWS does when a request processed. Rather, `have_statement` examines the literal contents of the IAM policy, and reports on what is present (or absent, when used with `should_not`).
188
188
 
189
- `have_statement` accepts the following criteria to search for matching statements. If any statement matches all the criteria, the test is successful.
189
+ `have_statement` accepts the following criteria to search for matching statements. If any statement matches all the criteria, the test is successful. All criteria may be used as Titlecase (as in the AWS examples) or lowercase, string or symbol.
190
190
 
191
191
  * `Action` - Expresses the requested operation. Acceptable literal values are any AWS operation name, including the '*' wildcard character. `Action` may also use a list of AWS operation names.
192
192
  * `Effect` - Expresses if the operation is permitted. Acceptable values are 'Deny' and 'Allow'.
@@ -204,7 +204,16 @@ Examples:
204
204
 
205
205
  # Verify there is no full-admin statement
206
206
  describe aws_iam_policy('kryptonite') do
207
+ it { should_not have_statement('Effect' => 'Allow', 'Resource' => '*', 'Action' => '*')}
208
+ end
209
+
210
+ # Symbols and lowercase also allowed as criteria
211
+ describe aws_iam_policy('kryptonite') do
212
+ # All 4 the same
213
+ it { should_not have_statement('Effect' => 'Allow', 'Resource' => '*', 'Action' => '*')}
214
+ it { should_not have_statement('effect' => 'Allow', 'resource' => '*', 'action' => '*')}
207
215
  it { should_not have_statement(Effect: 'Allow', Resource: '*', Action: '*')}
216
+ it { should_not have_statement(effect: 'Allow', resource: '*', action: '*')}
208
217
  end
209
218
 
210
219
  # Verify bob is allowed to manage things on S3 buckets that start with bobs-stuff
data/lib/inspec/rule.rb CHANGED
@@ -193,7 +193,7 @@ module Inspec
193
193
  [['describe', [resource], nil]]
194
194
  end
195
195
 
196
- def self.merge(dst, src)
196
+ def self.merge(dst, src) # rubocop:disable Metrics/AbcSize
197
197
  if src.id != dst.id
198
198
  # TODO: register an error, this case should not happen
199
199
  return
@@ -208,6 +208,15 @@ module Inspec
208
208
  dst.impact(src.impact) unless src.impact.nil?
209
209
  dst.title(src.title) unless src.title.nil?
210
210
  dst.desc(src.desc) unless src.desc.nil?
211
+ dst.tag(src.tag) unless src.tag.nil?
212
+ dst.ref(src.ref) unless src.ref.nil?
213
+
214
+ # use the most recent source location
215
+ dst.instance_variable_set(
216
+ :@__source_location,
217
+ src.instance_variable_get(:@__source_location),
218
+ )
219
+
211
220
  # merge indirect fields
212
221
  # checks defined in the source will completely eliminate
213
222
  # all checks that were defined in the destination
@@ -4,5 +4,5 @@
4
4
  # author: Christoph Hartmann
5
5
 
6
6
  module Inspec
7
- VERSION = '2.2.16'
7
+ VERSION = '2.2.20'
8
8
  end
@@ -30,11 +30,26 @@ module Inspec::Resources
30
30
  "
31
31
 
32
32
  def initialize
33
- @content = inspec.command('/sbin/auditctl -l').stdout.chomp
33
+ unless inspec.command('/sbin/auditctl').exist?
34
+ raise Inspec::Exceptions::ResourceFailed,
35
+ 'Command `/sbin/auditctl` does not exist'
36
+ end
37
+
38
+ auditctl_cmd = '/sbin/auditctl -l'
39
+ result = inspec.command(auditctl_cmd)
40
+
41
+ if result.exit_status != 0
42
+ raise Inspec::Exceptions::ResourceFailed,
43
+ "Command `#{auditctl_cmd}` failed with error: #{result.stderr}"
44
+ end
45
+
46
+ @content = result.stdout
34
47
  @params = []
35
48
 
36
49
  if @content =~ /^LIST_RULES:/
37
- return skip_resource 'The version of audit is outdated. The `auditd` resource supports versions of audit >= 2.3.'
50
+ raise Inspec::Exceptions::RsourceFailed,
51
+ 'The version of audit is outdated.' \
52
+ 'The `auditd` resource supports versions of audit >= 2.3.'
38
53
  end
39
54
  parse_content
40
55
  end
@@ -16,6 +16,7 @@ class AwsIamPolicy < Inspec.resource(1)
16
16
 
17
17
  attr_reader :arn, :attachment_count, :default_version_id
18
18
 
19
+ # Note that we also accept downcases and symbol versions of these
19
20
  EXPECTED_CRITERIA = %w{
20
21
  Action
21
22
  Effect
@@ -96,7 +97,7 @@ class AwsIamPolicy < Inspec.resource(1)
96
97
  def has_statement?(provided_criteria = {})
97
98
  return nil unless exists?
98
99
  raw_criteria = provided_criteria.dup # provided_criteria is used for output formatting - can't delete from it.
99
- criteria = has_statement__normalize_criteria(has_statement__validate_criteria(raw_criteria))
100
+ criteria = has_statement__validate_criteria(raw_criteria)
100
101
  @normalized_statements ||= has_statement__normalize_statements
101
102
  statements = has_statement__focus_on_sid(@normalized_statements, criteria)
102
103
  statements.any? do |statement|
@@ -112,15 +113,30 @@ class AwsIamPolicy < Inspec.resource(1)
112
113
  def has_statement__validate_criteria(raw_criteria)
113
114
  recognized_criteria = {}
114
115
  EXPECTED_CRITERIA.each do |expected_criterion|
115
- if raw_criteria.key?(expected_criterion)
116
- recognized_criteria[expected_criterion] = raw_criteria.delete(expected_criterion)
116
+ [
117
+ expected_criterion,
118
+ expected_criterion.downcase,
119
+ expected_criterion.to_sym,
120
+ expected_criterion.downcase.to_sym,
121
+ ].each do |variant|
122
+ if raw_criteria.key?(variant)
123
+ # Always store as downcased symbol
124
+ recognized_criteria[expected_criterion.downcase.to_sym] = raw_criteria.delete(variant)
125
+ end
117
126
  end
118
127
  end
119
128
 
120
129
  # Special message for valid, but unimplemented statement attributes
121
130
  UNIMPLEMENTED_CRITERIA.each do |unimplemented_criterion|
122
- if raw_criteria.key?(unimplemented_criterion)
123
- raise ArgumentError, "Criterion '#{unimplemented_criterion}' is not supported for performing have_statement queries."
131
+ [
132
+ unimplemented_criterion,
133
+ unimplemented_criterion.downcase,
134
+ unimplemented_criterion.to_sym,
135
+ unimplemented_criterion.downcase.to_sym,
136
+ ].each do |variant|
137
+ if raw_criteria.key?(variant)
138
+ raise ArgumentError, "Criterion '#{unimplemented_criterion}' is not supported for performing have_statement queries."
139
+ end
124
140
  end
125
141
  end
126
142
 
@@ -130,24 +146,15 @@ class AwsIamPolicy < Inspec.resource(1)
130
146
  end
131
147
 
132
148
  # Effect has only 2 permitted values
133
- if recognized_criteria.key?('Effect')
134
- unless %w{Allow Deny}.include?(recognized_criteria['Effect'])
135
- raise ArgumentError, "Criterion 'Effect' for have_statement must be one of 'Allow' or 'Deny' - got '#{recognized_criteria['Effect']}'"
149
+ if recognized_criteria.key?(:effect)
150
+ unless %w{Allow Deny}.include?(recognized_criteria[:effect])
151
+ raise ArgumentError, "Criterion 'Effect' for have_statement must be one of 'Allow' or 'Deny' - got '#{recognized_criteria[:effect]}'"
136
152
  end
137
153
  end
138
154
 
139
155
  recognized_criteria
140
156
  end
141
157
 
142
- def has_statement__normalize_criteria(criteria)
143
- # Transform keys into lowercase symbols
144
- criteria.keys.each do |provided_key|
145
- criteria[provided_key.downcase.to_sym] = criteria.delete(provided_key)
146
- end
147
-
148
- criteria
149
- end
150
-
151
158
  def has_statement__normalize_statements
152
159
  # Some single-statement policies place their statement
153
160
  # directly in policy['Statement'], rather than in an
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.16
4
+ version: 2.2.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominik Richter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-15 00:00:00.000000000 Z
11
+ date: 2018-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: train