inspec 1.4.1 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -2
- data/docs/resources/npm.md.erb +1 -1
- data/docs/resources/package.md.erb +1 -1
- data/docs/resources/pip.md.erb +3 -3
- data/docs/resources/powershell.md.erb +1 -1
- data/docs/resources/vbscript.md.erb +4 -4
- data/examples/meta-profile/README.md +31 -0
- data/examples/meta-profile/controls/example.rb +10 -4
- data/examples/meta-profile/inspec.yml +0 -4
- data/lib/bundles/inspec-compliance/target.rb +1 -1
- data/lib/bundles/inspec-supermarket/api.rb +3 -3
- data/lib/inspec/base_cli.rb +0 -2
- data/lib/inspec/cli.rb +25 -5
- data/lib/inspec/metadata.rb +5 -2
- data/lib/inspec/profile.rb +30 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/apt.rb +2 -1
- data/lib/source_readers/inspec.rb +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b497b451c9ceeebee2eaddce3fe68b30beacb61b
|
4
|
+
data.tar.gz: 788aab0d94d912e9ec52e05eaf781ce7ccf575eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70bf74fd78213f63be4607ba96fb7abd1282903c606e28ca469c080719c1a0886ae77a4a0b074361a7d5ec7f73a9dbb5852c9e25eb230117319a7c110e340077
|
7
|
+
data.tar.gz: 89eb02e30a5a1ebd6b1af5f6fa60ae2bca85411caee9c59f9fef97d9363bb2ef7f7da3a2cf67238b243b394b8819f1b90152ad53143ee2b8a3f08e15613834fb
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,30 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [1.
|
4
|
-
[Full Changelog](https://github.com/chef/inspec/compare/v1.4.
|
3
|
+
## [1.5.0](https://github.com/chef/inspec/tree/1.5.0) (2016-11-20)
|
4
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v1.4.1...1.5.0)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- inspec supermarket profiles - update for new supermarket api [\#1255](https://github.com/chef/inspec/issues/1255)
|
9
|
+
|
10
|
+
**Fixed bugs:**
|
11
|
+
|
12
|
+
- File resource permissions for windows [\#783](https://github.com/chef/inspec/issues/783)
|
13
|
+
- docs: quoted version for package resource example [\#1296](https://github.com/chef/inspec/pull/1296) ([alexpop](https://github.com/alexpop))
|
14
|
+
|
15
|
+
**Merged pull requests:**
|
16
|
+
|
17
|
+
- ensure metadata release entry is a string [\#1305](https://github.com/chef/inspec/pull/1305) ([chris-rock](https://github.com/chris-rock))
|
18
|
+
- Fixes resources in the docs [\#1303](https://github.com/chef/inspec/pull/1303) ([burtlo](https://github.com/burtlo))
|
19
|
+
- copy vendored dependencies into cache [\#1291](https://github.com/chef/inspec/pull/1291) ([chris-rock](https://github.com/chris-rock))
|
20
|
+
- fix double-log-level [\#1290](https://github.com/chef/inspec/pull/1290) ([chris-rock](https://github.com/chris-rock))
|
21
|
+
- update supermarket profile search to use new type param [\#1289](https://github.com/chef/inspec/pull/1289) ([robbkidd](https://github.com/robbkidd))
|
22
|
+
- Change `Inpsec` to `Inspec` [\#1286](https://github.com/chef/inspec/pull/1286) ([jerryaldrichiii](https://github.com/jerryaldrichiii))
|
23
|
+
- improve vendor command [\#1285](https://github.com/chef/inspec/pull/1285) ([chris-rock](https://github.com/chris-rock))
|
24
|
+
- improved regex for matching deb sources [\#1280](https://github.com/chef/inspec/pull/1280) ([grimm26](https://github.com/grimm26))
|
25
|
+
|
26
|
+
## [v1.4.1](https://github.com/chef/inspec/tree/v1.4.1) (2016-11-04)
|
27
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v1.4.0...v1.4.1)
|
5
28
|
|
6
29
|
**Fixed bugs:**
|
7
30
|
|
data/docs/resources/npm.md.erb
CHANGED
@@ -11,7 +11,7 @@ Use the `npm` InSpec audit resource to test if a global NPM package is installed
|
|
11
11
|
|
12
12
|
A `npm` resource block declares a package and (optionally) a package version:
|
13
13
|
|
14
|
-
describe
|
14
|
+
describe npm('npm_package_name') do
|
15
15
|
it { should be_installed }
|
16
16
|
end
|
17
17
|
|
@@ -64,7 +64,7 @@ The following examples show how to use this InSpec audit resource.
|
|
64
64
|
|
65
65
|
describe package('nginx') do
|
66
66
|
it { should be_installed }
|
67
|
-
its('version') { should eq 1.9.5 }
|
67
|
+
its('version') { should eq '1.9.5' }
|
68
68
|
end
|
69
69
|
|
70
70
|
### Test that a package is not installed
|
data/docs/resources/pip.md.erb
CHANGED
@@ -10,14 +10,14 @@ Use the `pip` InSpec audit resource to test packages that are installed using th
|
|
10
10
|
|
11
11
|
A `pip` resource block declares a package and (optionally) a package version:
|
12
12
|
|
13
|
-
describe pip('
|
13
|
+
describe pip('package_name') do
|
14
14
|
it { should be_installed }
|
15
15
|
end
|
16
16
|
|
17
17
|
where
|
18
18
|
|
19
|
-
* `'
|
20
|
-
* `be_installed` tests to see if the
|
19
|
+
* `'package_name'` is the name of the package, such as `'Jinja2'`
|
20
|
+
* `be_installed` tests to see if the package described above is installed
|
21
21
|
|
22
22
|
|
23
23
|
## Matchers
|
@@ -10,7 +10,7 @@ Use the `vbscript` InSpec audit resource to test a VBScript on the Windows platf
|
|
10
10
|
|
11
11
|
A `vbscript` resource block tests the output of a VBScript on the Windows platform:
|
12
12
|
|
13
|
-
describe vbscript('
|
13
|
+
describe vbscript('script contents') do
|
14
14
|
its('stdout') { should eq 'output' }
|
15
15
|
end
|
16
16
|
|
@@ -52,18 +52,18 @@ The following examples show how to use this InSpec audit resource.
|
|
52
52
|
|
53
53
|
A VBScript file similar to:
|
54
54
|
|
55
|
-
|
55
|
+
script = <<-EOH
|
56
56
|
WScript.Echo "hello"
|
57
57
|
EOH
|
58
58
|
|
59
59
|
may be tested for multiple lines:
|
60
60
|
|
61
|
-
describe vbscript(
|
61
|
+
describe vbscript(script) do
|
62
62
|
its('stdout') { should eq "hello\r\n" }
|
63
63
|
end
|
64
64
|
|
65
65
|
and tested for whitespace removal from standard output:
|
66
66
|
|
67
|
-
describe vbscript(
|
67
|
+
describe vbscript(script) do
|
68
68
|
its('strip') { should eq "hello" }
|
69
69
|
end
|
@@ -4,3 +4,34 @@ The inspec.yml file in this profile shows how one can use dependencies
|
|
4
4
|
from non-local sources such as Git or an HTTP url. This feature can
|
5
5
|
be used to build up a environment-wide profile that is based on more
|
6
6
|
specific profiles managed by others.
|
7
|
+
|
8
|
+
InSpec supports multiple profile locations:
|
9
|
+
|
10
|
+
```
|
11
|
+
depends:
|
12
|
+
# defaults to supermarket
|
13
|
+
- name: hardening/ssh-hardening
|
14
|
+
# remote tar or zip file
|
15
|
+
- name: os-hardening
|
16
|
+
url: https://github.com/dev-sec/tests-os-hardening/archive/master.zip
|
17
|
+
# git
|
18
|
+
- git: https://github.com/dev-sec/ssl-benchmark.git
|
19
|
+
- name: windows-patch-benchmark
|
20
|
+
git: https://github.com/chris-rock/windows-patch-benchmark.git
|
21
|
+
# Chef Compliance
|
22
|
+
- name: linux
|
23
|
+
compliance: base/linux
|
24
|
+
```
|
25
|
+
|
26
|
+
You could use those dependencies in your `exmaple.rb`:
|
27
|
+
|
28
|
+
```
|
29
|
+
|
30
|
+
include_controls 'hardening/ssh-hardening'
|
31
|
+
include_controls 'os-hardening'
|
32
|
+
include_controls 'ssl-benchmark'
|
33
|
+
include_controls 'linux'
|
34
|
+
include_controls 'windows-patch-benchmark'
|
35
|
+
```
|
36
|
+
|
37
|
+
Further details are described in our [InSpec Docs](http://inspec.io/docs/reference/profiles/)
|
@@ -1,8 +1,14 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
# copyright: 2015, The Authors
|
3
3
|
# license: All rights reserved
|
4
|
-
|
5
|
-
|
6
|
-
include_controls '
|
7
|
-
|
4
|
+
|
5
|
+
# import full profile
|
6
|
+
include_controls 'hardening/ssh-hardening'
|
7
|
+
|
8
|
+
# select only individual controls
|
9
|
+
include_controls 'ssl-benchmark' do
|
10
|
+
control "tls1.2"
|
11
|
+
end
|
12
|
+
|
13
|
+
# inspec knows that it cannot run Windows tests on Linux
|
8
14
|
include_controls 'windows-patch-benchmark'
|
@@ -8,10 +8,6 @@ summary: InSpec Profile that is only consuming dependencies
|
|
8
8
|
version: 0.2.0
|
9
9
|
depends:
|
10
10
|
- name: hardening/ssh-hardening # defaults to supermarket
|
11
|
-
- name: os-hardening
|
12
|
-
url: https://github.com/dev-sec/tests-os-hardening/archive/master.zip
|
13
11
|
- git: https://github.com/dev-sec/ssl-benchmark.git
|
14
12
|
- name: windows-patch-benchmark
|
15
13
|
git: https://github.com/chris-rock/windows-patch-benchmark.git
|
16
|
-
- name: linux
|
17
|
-
compliance: base/linux
|
@@ -40,7 +40,7 @@ EOF
|
|
40
40
|
# verifies that the target e.g base/ssh exists
|
41
41
|
profile = uri.host + uri.path
|
42
42
|
if !Compliance::API.exist?(config, profile)
|
43
|
-
fail
|
43
|
+
fail Inspec::FetcherFailure, "The compliance profile #{profile} was not found on the configured compliance server"
|
44
44
|
end
|
45
45
|
new(target_url(profile, config), config)
|
46
46
|
rescue URI::Error => _e
|
@@ -11,11 +11,11 @@ module Supermarket
|
|
11
11
|
|
12
12
|
# displays a list of profiles
|
13
13
|
def self.profiles(supermarket_url = SUPERMARKET_URL)
|
14
|
-
url = "#{supermarket_url}/api/v1/tools"
|
15
|
-
_success, data = get(url, {
|
14
|
+
url = "#{supermarket_url}/api/v1/tools-search"
|
15
|
+
_success, data = get(url, { type: 'compliance_profile', items: 100, order: 'recently_added' })
|
16
16
|
if !data.nil?
|
17
17
|
profiles = JSON.parse(data)
|
18
|
-
profiles['items'].
|
18
|
+
profiles['items'].map { |x|
|
19
19
|
m = %r{^#{supermarket_url}/api/v1/tools/(?<slug>[\w-]+)(/)?$}.match(x['tool'])
|
20
20
|
x['slug'] = m[:slug]
|
21
21
|
x
|
data/lib/inspec/base_cli.rb
CHANGED
@@ -44,8 +44,6 @@ module Inspec
|
|
44
44
|
desc: 'Allow remote scans with self-signed certificates (WinRM).'
|
45
45
|
option :json_config, type: :string,
|
46
46
|
desc: 'Read configuration from JSON file (`-` reads from stdin).'
|
47
|
-
option :log_level, aliases: :l, type: :string,
|
48
|
-
desc: 'Set the log level: info (default), debug, warn, error'
|
49
47
|
end
|
50
48
|
|
51
49
|
def self.profile_options
|
data/lib/inspec/cli.rb
CHANGED
@@ -105,16 +105,36 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
105
105
|
pretty_handle_exception(e)
|
106
106
|
end
|
107
107
|
|
108
|
-
desc 'vendor', 'Download all dependencies and generate a lockfile'
|
109
|
-
|
108
|
+
desc 'vendor PATH', 'Download all dependencies and generate a lockfile in a `vendor` directory'
|
109
|
+
option :overwrite, type: :boolean, default: false,
|
110
|
+
desc: 'Overwrite existing vendored dependencies and lockfile.'
|
111
|
+
def vendor(path = nil) # rubocop:disable Metrics/AbcSize
|
110
112
|
o = opts.dup
|
111
|
-
|
113
|
+
|
114
|
+
path.nil? ? path = Pathname.new(Dir.pwd) : path = Pathname.new(path)
|
115
|
+
cache_path = path.join('vendor')
|
116
|
+
inspec_lock = path.join('inspec.lock')
|
117
|
+
|
118
|
+
if (cache_path.exist? || inspec_lock.exist?) && !opts[:overwrite]
|
119
|
+
puts 'Profile is already vendored. Use --overwrite.'
|
120
|
+
return false
|
121
|
+
end
|
122
|
+
|
123
|
+
# remove existing
|
124
|
+
FileUtils.rm_rf(cache_path) if cache_path.exist?
|
125
|
+
File.delete(inspec_lock) if inspec_lock.exist?
|
126
|
+
|
127
|
+
puts "Vendor dependencies of #{path} into #{cache_path}"
|
128
|
+
o[:logger] = Logger.new(STDOUT)
|
129
|
+
o[:logger].level = get_log_level(o.log_level)
|
130
|
+
o[:cache] = Inspec::Cache.new(cache_path.to_s)
|
112
131
|
o[:backend] = Inspec::Backend.create(target: 'mock://')
|
113
132
|
configure_logger(o)
|
114
133
|
|
115
|
-
|
134
|
+
# vendor dependencies and generate lockfile
|
135
|
+
profile = Inspec::Profile.for_target(path.to_s, o)
|
116
136
|
lockfile = profile.generate_lockfile
|
117
|
-
File.write(
|
137
|
+
File.write(inspec_lock, lockfile.to_yaml)
|
118
138
|
rescue StandardError => e
|
119
139
|
pretty_handle_exception(e)
|
120
140
|
end
|
data/lib/inspec/metadata.rb
CHANGED
@@ -68,6 +68,7 @@ module Inspec
|
|
68
68
|
os.method(family_check).call
|
69
69
|
)
|
70
70
|
|
71
|
+
# ensure we do have a string if we have a non-nil value eg. 16.06
|
71
72
|
release_ok = release.nil? || os[:release] == release
|
72
73
|
|
73
74
|
# we want to make sure that all matchers are true
|
@@ -143,7 +144,9 @@ module Inspec
|
|
143
144
|
|
144
145
|
def self.finalize_supports_elem(elem, logger)
|
145
146
|
case x = elem
|
146
|
-
when Hash
|
147
|
+
when Hash
|
148
|
+
x[:release] = x[:release].to_s if x[:release]
|
149
|
+
x
|
147
150
|
when Array
|
148
151
|
logger.warn(
|
149
152
|
'Failed to read supports entry that is an array. Please use '\
|
@@ -162,7 +165,7 @@ module Inspec
|
|
162
165
|
|
163
166
|
def self.finalize_supports(supports, logger)
|
164
167
|
case x = supports
|
165
|
-
when Hash then [x]
|
168
|
+
when Hash then [finalize_supports_elem(x, logger)]
|
166
169
|
when Array then x.map { |e| finalize_supports_elem(e, logger) }.compact
|
167
170
|
when nil then []
|
168
171
|
else
|
data/lib/inspec/profile.rb
CHANGED
@@ -22,12 +22,41 @@ module Inspec
|
|
22
22
|
extend Forwardable
|
23
23
|
|
24
24
|
def self.resolve_target(target, cache = nil)
|
25
|
+
c = cache || Cache.new
|
26
|
+
Inspec::Log.debug "Resolve #{target} into cache #{c.path}"
|
25
27
|
Inspec::CachedFetcher.new(target, cache || Cache.new)
|
26
28
|
end
|
27
29
|
|
30
|
+
# Check if the profile contains a vendored cache, move content into global cache
|
31
|
+
# TODO: use relative file provider
|
32
|
+
# TODO: use source reader for Cache as well
|
33
|
+
def self.copy_deps_into_cache(file_provider, opts)
|
34
|
+
# filter content
|
35
|
+
cache = file_provider.files.find_all do |entry|
|
36
|
+
entry.start_with?('vendor')
|
37
|
+
end
|
38
|
+
content = Hash[cache.map { |x| [x, file_provider.read(x)] }]
|
39
|
+
keys = content.keys
|
40
|
+
keys.each do |key|
|
41
|
+
next if content[key].nil?
|
42
|
+
# remove prefix
|
43
|
+
rel = Pathname.new(key).relative_path_from(Pathname.new('vendor')).to_s
|
44
|
+
tar = Pathname.new(opts[:cache].path).join(rel)
|
45
|
+
|
46
|
+
FileUtils.mkdir_p tar.dirname.to_s
|
47
|
+
Inspec::Log.debug "Copy #{tar} to cache directory"
|
48
|
+
File.write(tar.to_s, content[key].force_encoding('UTF-8'))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
28
52
|
def self.for_path(path, opts)
|
29
53
|
file_provider = FileProvider.for_path(path)
|
30
|
-
|
54
|
+
rp = file_provider.relative_provider
|
55
|
+
|
56
|
+
# copy embedded dependecies into global cache
|
57
|
+
copy_deps_into_cache(rp, opts) unless opts[:cache].nil?
|
58
|
+
|
59
|
+
reader = Inspec::SourceReader.resolve(rp)
|
31
60
|
if reader.nil?
|
32
61
|
fail("Don't understand inspec profile in #{path}, it " \
|
33
62
|
"doesn't look like a supported profile structure.")
|
data/lib/inspec/version.rb
CHANGED
data/lib/resources/apt.rb
CHANGED
@@ -89,7 +89,8 @@ module Inspec::Resources
|
|
89
89
|
active = false if raw_line != line
|
90
90
|
|
91
91
|
# eg.: deb http://archive.ubuntu.com/ubuntu/ wily main restricted
|
92
|
-
|
92
|
+
# or : deb [trusted=yes] http://archive.ubuntu.com/ubuntu/ wily main restricted
|
93
|
+
parse_repo = /^\s*(\S+)\s+(?:\[\S+\])?\s*"?([^ "\t\r\n\f]+)"?\s+(\S+)\s+(.*)$/.match(line)
|
93
94
|
|
94
95
|
# check if we got any result and the second param is an url
|
95
96
|
next if parse_repo.nil? || !parse_repo[2] =~ HTTP_URL_RE
|
@@ -25,6 +25,10 @@ module SourceReaders
|
|
25
25
|
|
26
26
|
attr_reader :metadata, :tests, :libraries
|
27
27
|
|
28
|
+
# This create a new instance of an InSpec profile source reader
|
29
|
+
#
|
30
|
+
# @param [SourceReader] target
|
31
|
+
# @param [String] metadata_source eg. inspec.yml or metadata.rb
|
28
32
|
def initialize(target, metadata_source)
|
29
33
|
@target = target
|
30
34
|
@metadata = Inspec::Metadata.from_ref(
|
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: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dominik Richter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: train
|