inspec 1.0.0.beta2 → 1.0.0.beta3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -2
- data/Gemfile +4 -0
- data/Rakefile +2 -1
- data/docs/.gitignore +2 -0
- data/docs/README.md +21 -1
- data/docs/resources/apache_conf.md.erb +75 -0
- data/docs/resources/apt.md.erb +84 -0
- data/docs/resources/audit_policy.md.erb +61 -0
- data/docs/resources/auditd_conf.md.erb +79 -0
- data/docs/resources/auditd_rules.md.erb +132 -0
- data/docs/resources/bash.md.erb +84 -0
- data/docs/resources/bond.md.erb +97 -0
- data/docs/resources/bridge.md.erb +67 -0
- data/docs/resources/bsd_service.md.erb +76 -0
- data/docs/resources/command.md.erb +151 -0
- data/docs/resources/csv.md.erb +62 -0
- data/docs/resources/directory.md.erb +43 -0
- data/docs/resources/etc_group.md.erb +116 -0
- data/docs/resources/etc_passwd.md.erb +155 -0
- data/docs/resources/etc_shadow.md.erb +149 -0
- data/docs/resources/file.md.erb +460 -0
- data/docs/resources/gem.md.erb +73 -0
- data/docs/resources/group.md.erb +74 -0
- data/docs/resources/grub_conf.md.erb +115 -0
- data/docs/resources/host.md.erb +85 -0
- data/docs/resources/iis_site.md.erb +142 -0
- data/docs/resources/inetd_conf.md.erb +99 -0
- data/docs/resources/ini.md.erb +69 -0
- data/docs/resources/interface.md.erb +66 -0
- data/docs/resources/iptables.md.erb +70 -0
- data/docs/resources/json.md.erb +76 -0
- data/docs/resources/kernel_module.md.erb +60 -0
- data/docs/resources/kernel_parameter.md.erb +72 -0
- data/docs/resources/launchd_service.md.erb +76 -0
- data/docs/resources/limits_conf.md.erb +80 -0
- data/docs/resources/login_def.md.erb +77 -0
- data/docs/resources/mount.md.erb +83 -0
- data/docs/resources/mysql_conf.md.erb +102 -0
- data/docs/resources/mysql_session.md.erb +63 -0
- data/docs/resources/npm.md.erb +75 -0
- data/docs/resources/ntp_conf.md.erb +76 -0
- data/docs/resources/oneget.md.erb +67 -0
- data/docs/resources/os.md.erb +154 -0
- data/docs/resources/os_env.md.erb +98 -0
- data/docs/resources/package.md.erb +115 -0
- data/docs/resources/parse_config.md.erb +122 -0
- data/docs/resources/parse_config_file.md.erb +143 -0
- data/docs/resources/pip.md.erb +74 -0
- data/docs/resources/port.md.erb +150 -0
- data/docs/resources/postgres_conf.md.erb +90 -0
- data/docs/resources/postgres_session.md.erb +75 -0
- data/docs/resources/powershell.md.erb +116 -0
- data/docs/resources/process.md.erb +73 -0
- data/docs/resources/registry_key.md.erb +149 -0
- data/docs/resources/runit_service.md.erb +76 -0
- data/docs/resources/security_policy.md.erb +61 -0
- data/docs/resources/service.md.erb +135 -0
- data/docs/resources/ssh_config.md.erb +94 -0
- data/docs/resources/sshd_config.md.erb +97 -0
- data/docs/resources/ssl.md.erb +133 -0
- data/docs/resources/sys_info.md.erb +55 -0
- data/docs/resources/systemd_service.md.erb +76 -0
- data/docs/resources/sysv_service.md.erb +76 -0
- data/docs/resources/upstart_service.md.erb +76 -0
- data/docs/resources/user.md.erb +154 -0
- data/docs/resources/users.md.erb +140 -0
- data/docs/resources/vbscript.md.erb +69 -0
- data/docs/resources/windows_feature.md.erb +61 -0
- data/docs/resources/wmi.md.erb +95 -0
- data/docs/resources/xinetd_conf.md.erb +170 -0
- data/docs/resources/yaml.md.erb +69 -0
- data/docs/resources/yum.md.erb +103 -0
- data/docs/ruby_usage.md +154 -0
- data/docs/shared/matcher_be.md.erb +1 -0
- data/docs/shared/matcher_cmp.md.erb +45 -0
- data/docs/shared/matcher_eq.md.erb +3 -0
- data/docs/shared/matcher_include.md.erb +1 -0
- data/docs/shared/matcher_match.md.erb +1 -0
- data/lib/fetchers/url.rb +27 -29
- data/lib/inspec/cached_fetcher.rb +67 -0
- data/lib/inspec/dependencies/requirement.rb +6 -7
- data/lib/inspec/objects/each_loop.rb +5 -2
- data/lib/inspec/plugins/fetcher.rb +2 -0
- data/lib/inspec/profile.rb +9 -41
- data/lib/inspec/resource.rb +1 -1
- data/lib/inspec/rspec_json_formatter.rb +11 -5
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/groups.rb +190 -0
- data/lib/resources/users.rb +3 -2
- metadata +79 -6
- data/docs/cli.rst +0 -448
- data/docs/resources.rst +0 -4836
- data/docs/ruby_usage.rst +0 -145
- data/lib/resources/group.rb +0 -137
@@ -0,0 +1,170 @@
|
|
1
|
+
---
|
2
|
+
title: About the xinetd_conf Resource
|
3
|
+
---
|
4
|
+
|
5
|
+
# xinetd_conf
|
6
|
+
|
7
|
+
Use the `xinetd_conf` InSpec audit resource to test services under `/etc/xinet.d` on Linux and Unix platforms. xinetd---the extended Internet service daemon---listens on all ports, and then loads the appropriate program based on a request. The `xinetd.conf` file is typically located at `/etc/xinetd.conf` and contains a list of Internet services associated to the ports on which that service will listen. Only enabled services may handle a request; only services that are required by the system should be enabled.
|
8
|
+
|
9
|
+
# Syntax
|
10
|
+
|
11
|
+
An `xinetd_conf` resource block declares settings found in a `xinetd.conf` file for the named service:
|
12
|
+
|
13
|
+
describe xinetd_conf('service_name') do
|
14
|
+
it { should be_enabled } # or be_disabled
|
15
|
+
its('setting') { should eq 'value' }
|
16
|
+
end
|
17
|
+
|
18
|
+
where
|
19
|
+
|
20
|
+
* `'service_name'` is a service located under `/etc/xinet.d`
|
21
|
+
* `('setting')` is a setting in the `xinetd.conf` file
|
22
|
+
* `should eq 'value'` is the value that is expected
|
23
|
+
|
24
|
+
|
25
|
+
# Matchers
|
26
|
+
|
27
|
+
This InSpec audit resource has the following matchers:
|
28
|
+
|
29
|
+
## be
|
30
|
+
|
31
|
+
<%= partial "/shared/matcher_be" %>
|
32
|
+
|
33
|
+
## be_enabed
|
34
|
+
|
35
|
+
The `be_enabled` matcher tests if a service listed under `/etc/xinet.d` is enabled:
|
36
|
+
|
37
|
+
it { should be_enabled }
|
38
|
+
|
39
|
+
## cmp
|
40
|
+
|
41
|
+
<%= partial "/shared/matcher_cmp" %>
|
42
|
+
|
43
|
+
## eq
|
44
|
+
|
45
|
+
<%= partial "/shared/matcher_eq" %>
|
46
|
+
|
47
|
+
## ids
|
48
|
+
|
49
|
+
The `ids` matcher tests if the named service is located under `/etc/xinet.d`:
|
50
|
+
|
51
|
+
its('ids') { should include 'service_name' }
|
52
|
+
|
53
|
+
For example:
|
54
|
+
|
55
|
+
its('ids') { should include 'chargen-stream chargen-dgram'}
|
56
|
+
|
57
|
+
## include
|
58
|
+
|
59
|
+
<%= partial "/shared/matcher_include" %>
|
60
|
+
|
61
|
+
## match
|
62
|
+
|
63
|
+
<%= partial "/shared/matcher_match" %>
|
64
|
+
|
65
|
+
## services
|
66
|
+
|
67
|
+
The `services` matcher tests if the named service is listed under `/etc/xinet.d`:
|
68
|
+
|
69
|
+
its('services') { should include 'service_name' }
|
70
|
+
|
71
|
+
## socket_types
|
72
|
+
|
73
|
+
The `socket_types` matcher tests if a service listed under `/etc/xinet.d` is configured to use the named socket type:
|
74
|
+
|
75
|
+
its('socket_types') { should eq 'socket' }
|
76
|
+
|
77
|
+
where `socket` is one of `dgram`, `raw`, or `stream`. For a UDP-based service:
|
78
|
+
|
79
|
+
its('socket_types') { should eq 'dgram' }
|
80
|
+
|
81
|
+
For a raw socket (such as a service using a non-standard protocol or a service that requires direct access to IP):
|
82
|
+
|
83
|
+
its('socket_types') { should eq 'raw' }
|
84
|
+
|
85
|
+
For a TCP-based service:
|
86
|
+
|
87
|
+
its('socket_types') { should eq 'stream' }
|
88
|
+
|
89
|
+
## types
|
90
|
+
|
91
|
+
The `types` matcher tests the service type:
|
92
|
+
|
93
|
+
its('type') { should eq 'TYPE' }
|
94
|
+
|
95
|
+
where `'TYPE'` is `INTERNAL` (for a service provided by xinetd), `RPC` (for a service based on remote procedure call), or `UNLISTED` (for services not under `/etc/services` or `/etc/rpc`).
|
96
|
+
|
97
|
+
## wait
|
98
|
+
|
99
|
+
The `wait` matcher tests how a service handles incoming connections.
|
100
|
+
|
101
|
+
For UDP (`dgram`) socket types the `wait` matcher should test for `yes`:
|
102
|
+
|
103
|
+
its('socket_types') { should eq 'dgram' }
|
104
|
+
its('wait') { should eq 'yes' }
|
105
|
+
|
106
|
+
For TCP (`stream`) socket types the `wait` matcher should test for `no`:
|
107
|
+
|
108
|
+
its('socket_types') { should eq 'stream' }
|
109
|
+
its('wait') { should eq 'no' }
|
110
|
+
|
111
|
+
# Examples
|
112
|
+
|
113
|
+
The following examples show how to use this InSpec audit resource.
|
114
|
+
|
115
|
+
## Test a socket_type
|
116
|
+
|
117
|
+
The network socket type: `dgram` (a datagram-based service), `raw` (a service that requires direct access to an IP address), `stream` (a stream-based service), or `seqpacket` (a service that requires a sequenced packet).
|
118
|
+
|
119
|
+
describe xinetd_conf.services('service_name') do
|
120
|
+
its('socket_types') { should include 'dgram' }
|
121
|
+
end
|
122
|
+
|
123
|
+
## Test a service type
|
124
|
+
|
125
|
+
The type of service: `INTERNAL` (a service provided by xinetd), `RPC` (an RPC-based service), `TCPMUX` (a service that is started on a well-known TPCMUX port), or `UNLISTED` (a service that is not listed in a standard system file location).
|
126
|
+
|
127
|
+
describe xinetd_conf.services('service_name') do
|
128
|
+
its('type') { should include 'RPC' }
|
129
|
+
end
|
130
|
+
|
131
|
+
## Test the telnet service
|
132
|
+
|
133
|
+
For example, a `telnet` file under `/etc/xinet.d` contains the following settings:
|
134
|
+
|
135
|
+
service telnet
|
136
|
+
{
|
137
|
+
disable = yes
|
138
|
+
flags = REUSE
|
139
|
+
socket_type = stream
|
140
|
+
wait = no
|
141
|
+
user = root
|
142
|
+
server = /usr/sbin/in.telnetd
|
143
|
+
log_on_failure += USERID
|
144
|
+
}
|
145
|
+
|
146
|
+
Some examples of tests that can be run against that file include:
|
147
|
+
|
148
|
+
describe xinetd_conf.services('telnet') do
|
149
|
+
it { should be_disabled }
|
150
|
+
end
|
151
|
+
|
152
|
+
and
|
153
|
+
|
154
|
+
describe xinetd_conf.services('telnet') do
|
155
|
+
its('socket_type') { should include 'stream' }
|
156
|
+
end
|
157
|
+
|
158
|
+
and
|
159
|
+
|
160
|
+
describe xinetd_conf.services('telnet') do
|
161
|
+
its('wait') { should eq 'no' }
|
162
|
+
end
|
163
|
+
|
164
|
+
All three settings can be tested in the same block as well:
|
165
|
+
|
166
|
+
describe xinetd_conf.services('telnet') do
|
167
|
+
it { should be_disabled }
|
168
|
+
its('socket_type') { should include 'stream' }
|
169
|
+
its('wait') { should eq 'no' }
|
170
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
---
|
2
|
+
title: About the yaml Resource
|
3
|
+
---
|
4
|
+
|
5
|
+
# yaml
|
6
|
+
|
7
|
+
Use the `yaml` InSpec audit resource to test configuration data in a Yaml file.
|
8
|
+
|
9
|
+
# Syntax
|
10
|
+
|
11
|
+
A `yaml` resource block declares the configuration data to be tested. Assume the following Yaml file:
|
12
|
+
|
13
|
+
name: foo
|
14
|
+
array:
|
15
|
+
- zero
|
16
|
+
- one
|
17
|
+
|
18
|
+
This file can be queried using:
|
19
|
+
|
20
|
+
describe yaml do
|
21
|
+
its('name') { should eq 'foo' }
|
22
|
+
its(['array', 1]) { should eq 'one' }
|
23
|
+
end
|
24
|
+
|
25
|
+
where
|
26
|
+
|
27
|
+
* `name` is a configuration setting in a Yaml file
|
28
|
+
* `should eq 'foo'` tests a value of `name` as read from a Yaml file versus the value declared in the test
|
29
|
+
|
30
|
+
|
31
|
+
# Matchers
|
32
|
+
|
33
|
+
This InSpec audit resource has the following matchers:
|
34
|
+
|
35
|
+
## be
|
36
|
+
|
37
|
+
<%= partial "/shared/matcher_be" %>
|
38
|
+
|
39
|
+
## cmp
|
40
|
+
|
41
|
+
<%= partial "/shared/matcher_cmp" %>
|
42
|
+
|
43
|
+
## eq
|
44
|
+
|
45
|
+
<%= partial "/shared/matcher_eq" %>
|
46
|
+
|
47
|
+
## include
|
48
|
+
|
49
|
+
<%= partial "/shared/matcher_include" %>
|
50
|
+
|
51
|
+
## match
|
52
|
+
|
53
|
+
<%= partial "/shared/matcher_match" %>
|
54
|
+
|
55
|
+
## name
|
56
|
+
|
57
|
+
The `name` matcher tests the value of `name` as read from a Yaml file versus the value declared in the test:
|
58
|
+
|
59
|
+
its('name') { should eq 'foo' }
|
60
|
+
|
61
|
+
# Examples
|
62
|
+
|
63
|
+
The following examples show how to use this InSpec audit resource.
|
64
|
+
|
65
|
+
## Test a kitchen.yml file driver
|
66
|
+
|
67
|
+
describe yaml('.kitchen.yaml') do
|
68
|
+
its('driver.name') { should eq('vagrant') }
|
69
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
---
|
2
|
+
title: About the yum Resource
|
3
|
+
---
|
4
|
+
|
5
|
+
# yum
|
6
|
+
|
7
|
+
Use the `yum` InSpec audit resource to test packages in the Yum repository.
|
8
|
+
|
9
|
+
# Syntax
|
10
|
+
|
11
|
+
A `yum` resource block declares a package repo, tests if the package repository is present, and if it that package repository is a valid package source (i.e. "is enabled"):
|
12
|
+
|
13
|
+
describe yum.repo('name') do
|
14
|
+
it { should exist }
|
15
|
+
it { should be_enabled }
|
16
|
+
end
|
17
|
+
|
18
|
+
where
|
19
|
+
|
20
|
+
* `repo('name')` is the (optional) name of a package repo, using either a full identifier (`'updates/7/x86_64'`) or a short identifier (`'updates'`)
|
21
|
+
|
22
|
+
# Matchers
|
23
|
+
|
24
|
+
This InSpec audit resource has the following matchers:
|
25
|
+
|
26
|
+
## be
|
27
|
+
|
28
|
+
<%= partial "/shared/matcher_be" %>
|
29
|
+
|
30
|
+
## be_enabled
|
31
|
+
|
32
|
+
The `be_enabled` matcher tests if the package repository is a valid package source:
|
33
|
+
|
34
|
+
it { should be_enabled }
|
35
|
+
|
36
|
+
## cmp
|
37
|
+
|
38
|
+
<%= partial "/shared/matcher_cmp" %>
|
39
|
+
|
40
|
+
## eq
|
41
|
+
|
42
|
+
<%= partial "/shared/matcher_eq" %>
|
43
|
+
|
44
|
+
## exist
|
45
|
+
|
46
|
+
The `exist` matcher tests if the package repository exists:
|
47
|
+
|
48
|
+
it { should exist }
|
49
|
+
|
50
|
+
## include
|
51
|
+
|
52
|
+
<%= partial "/shared/matcher_include" %>
|
53
|
+
|
54
|
+
## match
|
55
|
+
|
56
|
+
<%= partial "/shared/matcher_match" %>
|
57
|
+
|
58
|
+
## repo('name')
|
59
|
+
|
60
|
+
The `repo('name')` matcher names a specific package repository:
|
61
|
+
|
62
|
+
describe yum.repo('epel') do
|
63
|
+
...
|
64
|
+
end
|
65
|
+
|
66
|
+
## repos
|
67
|
+
|
68
|
+
The `repos` matcher tests if a named repo, using either a full identifier (`'updates/7/x86_64'`) or a short identifier (`'updates'`), is included in the Yum repo:
|
69
|
+
|
70
|
+
its('repos') { should include 'some_repo' }
|
71
|
+
|
72
|
+
## shortname
|
73
|
+
|
74
|
+
The `shortname` matcher names a specific package repository's group identifier. For example, if a repository's group name is "Directory Server", the corresponding group idenfier is typically "directory-server":
|
75
|
+
|
76
|
+
describe yum.repo('Directory Server') do
|
77
|
+
its('shortname') { should eq 'directory-server' }
|
78
|
+
end
|
79
|
+
|
80
|
+
# Examples
|
81
|
+
|
82
|
+
The following examples show how to use this InSpec audit resource.
|
83
|
+
|
84
|
+
## Test if the yum repo exists
|
85
|
+
|
86
|
+
describe yum do
|
87
|
+
its('repos') { should exist }
|
88
|
+
end
|
89
|
+
|
90
|
+
## Test if the 'base/7/x86_64' repo exists and is enabled
|
91
|
+
|
92
|
+
describe yum do
|
93
|
+
its('repos') { should include 'base/7/x86_64' }
|
94
|
+
its('epel') { should exist }
|
95
|
+
its('epel') { should be_enabled }
|
96
|
+
end
|
97
|
+
|
98
|
+
## Test if a specific yum repo exists
|
99
|
+
|
100
|
+
describe yum.repo('epel') do
|
101
|
+
it { should exist }
|
102
|
+
it { should be_enabled }
|
103
|
+
end
|
data/docs/ruby_usage.md
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
# Using Ruby in InSpec
|
2
|
+
|
3
|
+
The InSpec DSL is a Ruby based DSL for writing audit controls, which
|
4
|
+
includes audit resources that you can invoke. Core and custom resources
|
5
|
+
are written as regular Ruby classes which inherit from
|
6
|
+
`Inspec.resource`.
|
7
|
+
|
8
|
+
Assuming we have a JSON file like this on the node to be tested:
|
9
|
+
|
10
|
+
```json
|
11
|
+
{
|
12
|
+
"keys":[
|
13
|
+
{"username":"john", "key":"/opt/keys/johnd.key"},
|
14
|
+
{"username":"jane", "key":"/opt/keys/janed.key"},
|
15
|
+
{"username":"sunny ", "key":"/opt/keys/sunnym.key"}
|
16
|
+
]
|
17
|
+
}
|
18
|
+
```
|
19
|
+
|
20
|
+
The following example shows how you can use pure Ruby code(variables,
|
21
|
+
loops, conditionals, regular expressions, etc) to run a few tests
|
22
|
+
against the above JSON file:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
control 'check-interns' do
|
26
|
+
# use the json inspec resource to get the file
|
27
|
+
json_obj = json('/opt/keys/interns.json')
|
28
|
+
describe json_obj do
|
29
|
+
its('keys') { should_not eq nil }
|
30
|
+
end
|
31
|
+
if json_obj['keys']
|
32
|
+
# loop over the keys array
|
33
|
+
json_obj['keys'].each do |intern|
|
34
|
+
username = intern['username'].strip
|
35
|
+
# check for white spaces chars in usernames
|
36
|
+
describe username do
|
37
|
+
it { should_not match(/\s/) }
|
38
|
+
end
|
39
|
+
# check key file owners and permissions
|
40
|
+
describe file(intern['key']) do
|
41
|
+
it { should be_owned_by username }
|
42
|
+
its('mode') { should cmp '0600' }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
## Execution
|
50
|
+
|
51
|
+
It's important to understand that Ruby code used in custom resources and
|
52
|
+
controls DSL is executed on the system that runs InSpec. This allows
|
53
|
+
InSpec to work without Ruby and rubygems being required on remote
|
54
|
+
targets(servers or containers).
|
55
|
+
|
56
|
+
For example, using `` `ls ``\` or `system('ls')` will result in the `ls`
|
57
|
+
command being run locally and not on the target(remote) system. In order
|
58
|
+
to process the output of `ls` executed on the target system, use
|
59
|
+
`inspec.command('ls')` or `inspec.powershell('ls')`
|
60
|
+
|
61
|
+
Similarly, use `inspec.file(PATH)` to access files or directories from
|
62
|
+
remote systems in your tests or custom resources.
|
63
|
+
|
64
|
+
|
65
|
+
## Using rubygems
|
66
|
+
|
67
|
+
Ruby gems are self-contained programs and libraries. If you create a custom
|
68
|
+
resource please vendor gems into the library. This ensures that all resources
|
69
|
+
are self-contained and complete and don't need any resolution at runtime. We
|
70
|
+
vendor resources and requirements through dependency resolution, which is
|
71
|
+
independent of programming languages and their resolver mechanisms.
|
72
|
+
|
73
|
+
## Interactive Debugging with Pry
|
74
|
+
|
75
|
+
Here's a sample InSpec control that users Ruby variables to instantiate
|
76
|
+
an InSpec resource once and use the content in multipLe tests.
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
control 'check-perl' do
|
80
|
+
impact 0.3
|
81
|
+
title 'Check perl compiled options and permissions'
|
82
|
+
perl_out = command('perl -V')
|
83
|
+
#require 'pry'; binding.pry;
|
84
|
+
describe perl_out do
|
85
|
+
its('exit_status') { should eq 0 }
|
86
|
+
its('stdout') { should match (/USE_64_BIT_ALL/) }
|
87
|
+
its('stdout') { should match (/useposix=true/) }
|
88
|
+
its('stdout') { should match (/-fstack-protector/) }
|
89
|
+
end
|
90
|
+
|
91
|
+
# extract an array of include directories
|
92
|
+
perl_inc = perl_out.stdout.partition('@INC:').last.strip.split("\n")
|
93
|
+
# ensure include directories are only writable by 'owner'
|
94
|
+
perl_inc.each do |path|
|
95
|
+
describe directory(path.strip) do
|
96
|
+
it { should_not be_writable.by('group') }
|
97
|
+
it { should_not be_writable.by('other') }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
```
|
102
|
+
|
103
|
+
An **advanced** but very useful Ruby tip. In the previous example, I
|
104
|
+
commented out the `require 'pry'; binding.pry;` line. If you remove the
|
105
|
+
`#` prefix and run the control, the execution will stop at that line and
|
106
|
+
give you a `pry` shell. Use that to troubleshoot, print variables, see
|
107
|
+
methods available, etc. For the above example:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
[1] pry> perl_out.exit_status
|
111
|
+
=> 0
|
112
|
+
[2] pry> perl_out.stderr
|
113
|
+
=> ""
|
114
|
+
[3] pry> ls perl_out
|
115
|
+
Inspec::Plugins::Resource#methods: inspect
|
116
|
+
Inspec::Resources::Cmd#methods: command exist? exit_status result stderr stdout to_s
|
117
|
+
Inspec::Plugins::ResourceCommon#methods: resource_skipped skip_resource
|
118
|
+
Inspec::Resource::Registry::Command#methods: inspec
|
119
|
+
instance variables: @__backend_runner__ @__resource_name__ @command @result
|
120
|
+
[4] pry> perl_out.stdout.partition('@INC:').last.strip.split("\n")
|
121
|
+
=> ["/Library/Perl/5.18/darwin-thread-multi-2level",
|
122
|
+
" /Library/Perl/5.18",
|
123
|
+
...REDACTED...
|
124
|
+
[5] pry> exit # or abort
|
125
|
+
```
|
126
|
+
|
127
|
+
You can use `pry` inside both the controls DSL and resources. Similarly,
|
128
|
+
for dev and test, you can use `inspec shell` which is based on `pry`,
|
129
|
+
for example:
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
$ inspec shell
|
133
|
+
Welcome to the interactive InSpec Shell
|
134
|
+
To find out how to use it, type: help
|
135
|
+
|
136
|
+
inspec> command('ls /home/gordon/git/inspec/docs').stdout
|
137
|
+
=> "ctl_inspec.rst\ndsl_inspec.rst\ndsl_resource.rst\n"
|
138
|
+
inspec> command('ls').stdout.split("\n")
|
139
|
+
=> ["ctl_inspec.rst", "dsl_inspec.rst", "dsl_resource.rst"]
|
140
|
+
|
141
|
+
inspec> help command
|
142
|
+
Name: command
|
143
|
+
|
144
|
+
Description:
|
145
|
+
Use the command InSpec audit resource to test an arbitrary command that is run on the system.
|
146
|
+
|
147
|
+
Example:
|
148
|
+
describe command('ls -al /') do
|
149
|
+
it { should exist }
|
150
|
+
its('stdout') { should match /bin/ }
|
151
|
+
its('stderr') { should eq '' }
|
152
|
+
its('exit_status') { should eq 0 }
|
153
|
+
end
|
154
|
+
```
|