inspec 0.23 → 0.24.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 +13 -2
- data/docs/resources.rst +4 -4
- data/lib/inspec/profile_context.rb +44 -2
- data/lib/inspec/require_loader.rb +33 -0
- data/lib/inspec/runner.rb +1 -4
- data/lib/inspec/version.rb +1 -1
- data/lib/utils/hash_map.rb +37 -0
- data/test/functional/inspec_exec_test.rb +8 -0
- data/test/unit/mock/profiles/library/controls/filesystem_spec.rb +7 -0
- data/test/unit/mock/profiles/library/inspec.yml +10 -0
- data/test/unit/mock/profiles/library/libraries/gordonlib.rb +2 -0
- data/test/unit/mock/profiles/library/libraries/testlib.rb +12 -0
- data/test/unit/mock/profiles/resource-tiny/inspec.yml +10 -0
- data/test/unit/mock/profiles/resource-tiny/libraries/resource.rb +3 -0
- data/test/unit/profile_context_test.rb +35 -0
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cdee2bef2b5cae85b1427243ae5013641ec00de9
|
4
|
+
data.tar.gz: ff0b32c16345ee013475a10254c52afc1780e49e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e54f5100590735780ec9815a570f7171c3297a2747c9dbd7c40d7c8fe099acd36000ee74cd05e1269ea4ebb2b06276dc46f0c551547da2a3060b7aa861d7cb3
|
7
|
+
data.tar.gz: eb40755a53b7e4f9d5fa264b92a778829833835ca77d81a8ba91b59fb0b057f6a7981a47ab87336832bed17b691c2b13d70594a83c83d08a83f1b1770ed75716
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,18 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [0.
|
4
|
-
[Full Changelog](https://github.com/chef/inspec/compare/v0.
|
3
|
+
## [0.24.0](https://github.com/chef/inspec/tree/0.24.0) (2016-06-03)
|
4
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v0.23...0.24.0)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- support intra-libraries file referencing + loading [\#780](https://github.com/chef/inspec/pull/780) ([arlimus](https://github.com/arlimus))
|
9
|
+
|
10
|
+
**Merged pull requests:**
|
11
|
+
|
12
|
+
- Update documentation for matching output of commands [\#777](https://github.com/chef/inspec/pull/777) ([tas50](https://github.com/tas50))
|
13
|
+
|
14
|
+
## [v0.23](https://github.com/chef/inspec/tree/v0.23) (2016-05-31)
|
15
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v0.22.1...v0.23)
|
5
16
|
|
6
17
|
**Implemented enhancements:**
|
7
18
|
|
data/docs/resources.rst
CHANGED
@@ -628,7 +628,7 @@ The ``stdout`` matcher tests results of the command as returned in standard outp
|
|
628
628
|
|
629
629
|
.. code-block:: ruby
|
630
630
|
|
631
|
-
its('stdout') { should
|
631
|
+
its('stdout') { should match /^1$/ }
|
632
632
|
|
633
633
|
Examples
|
634
634
|
-----------------------------------------------------
|
@@ -639,9 +639,9 @@ The following examples show how to use this InSpec audit resource.
|
|
639
639
|
.. code-block:: ruby
|
640
640
|
|
641
641
|
describe command('psql -V') do
|
642
|
-
its('stdout') { should
|
643
|
-
its('stdout') { should_not
|
644
|
-
its('stdout') { should_not
|
642
|
+
its('stdout') { should match /RC/ }
|
643
|
+
its('stdout') { should_not match /DEVEL/ }
|
644
|
+
its('stdout') { should_not match /BETA/ }
|
645
645
|
end
|
646
646
|
|
647
647
|
**Test standard output (stdout)**
|
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
require 'inspec/rule'
|
6
6
|
require 'inspec/dsl'
|
7
|
+
require 'inspec/require_loader'
|
7
8
|
require 'securerandom'
|
8
9
|
|
9
10
|
module Inspec
|
@@ -19,6 +20,7 @@ module Inspec
|
|
19
20
|
@backend = backend
|
20
21
|
@conf = conf.dup
|
21
22
|
@rules = {}
|
23
|
+
@require_loader = ::Inspec::RequireLoader.new
|
22
24
|
|
23
25
|
reload_dsl
|
24
26
|
end
|
@@ -26,7 +28,30 @@ module Inspec
|
|
26
28
|
def reload_dsl
|
27
29
|
resources_dsl = Inspec::Resource.create_dsl(@backend)
|
28
30
|
ctx = create_context(resources_dsl, rule_context(resources_dsl))
|
29
|
-
@profile_context = ctx.new(@backend, @conf)
|
31
|
+
@profile_context = ctx.new(@backend, @conf, @require_loader)
|
32
|
+
end
|
33
|
+
|
34
|
+
def load_libraries(libs)
|
35
|
+
lib_prefix = 'libraries' + File::SEPARATOR
|
36
|
+
autoloads = []
|
37
|
+
|
38
|
+
libs.each do |content, source, line|
|
39
|
+
path = source
|
40
|
+
if source.start_with?(lib_prefix)
|
41
|
+
path = source.sub(lib_prefix, '')
|
42
|
+
autoloads.push(path) if File.dirname(path) == '.'
|
43
|
+
end
|
44
|
+
|
45
|
+
@require_loader.add(path, content, source, line)
|
46
|
+
end
|
47
|
+
|
48
|
+
# load all files directly that are flat inside the libraries folder
|
49
|
+
autoloads.each do |path|
|
50
|
+
next unless path.end_with?('.rb')
|
51
|
+
load(*@require_loader.load(path)) unless @require_loader.loaded?(path)
|
52
|
+
end
|
53
|
+
|
54
|
+
reload_dsl
|
30
55
|
end
|
31
56
|
|
32
57
|
def load(content, source = nil, line = nil)
|
@@ -100,12 +125,29 @@ module Inspec
|
|
100
125
|
include Inspec::DSL
|
101
126
|
include resources_dsl
|
102
127
|
|
103
|
-
def initialize(backend, conf) # rubocop:disable Lint/NestedMethodDefinition, Lint/DuplicateMethods
|
128
|
+
def initialize(backend, conf, require_loader) # rubocop:disable Lint/NestedMethodDefinition, Lint/DuplicateMethods
|
104
129
|
@backend = backend
|
105
130
|
@conf = conf
|
131
|
+
@require_loader = require_loader
|
106
132
|
@skip_profile = false
|
107
133
|
end
|
108
134
|
|
135
|
+
# Save the toplevel require method to load all ruby dependencies.
|
136
|
+
# It is used whenever the `require 'lib'` is not in libraries.
|
137
|
+
alias_method :__ruby_require, :require
|
138
|
+
|
139
|
+
def require(path)
|
140
|
+
rbpath = path + '.rb'
|
141
|
+
return __ruby_require(path) if !@require_loader.exists?(rbpath)
|
142
|
+
return false if @require_loader.loaded?(rbpath)
|
143
|
+
|
144
|
+
# This is equivalent to calling `require 'lib'` with lib on disk.
|
145
|
+
# We cannot rely on libraries residing on disk however.
|
146
|
+
# TODO: Sandboxing.
|
147
|
+
content, path, line = @require_loader.load(rbpath)
|
148
|
+
eval(content, TOPLEVEL_BINDING, path, line) # rubocop:disable Lint/Eval
|
149
|
+
end
|
150
|
+
|
109
151
|
define_method :title do |arg|
|
110
152
|
profile_context_owner.set_header(:title, arg)
|
111
153
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Dominik Richter
|
3
|
+
# author: Christoph Hartmann
|
4
|
+
|
5
|
+
module Inspec
|
6
|
+
class RequireLoader
|
7
|
+
Item = Struct.new(:content, :ref, :line, :loaded)
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@contents = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def add(path, content, ref, line)
|
14
|
+
@contents[path] = Item.new(content, ref, line, false)
|
15
|
+
end
|
16
|
+
|
17
|
+
def load(path)
|
18
|
+
c = @contents[path]
|
19
|
+
c.loaded = true
|
20
|
+
res = [c.content, c.ref, c.line || 1]
|
21
|
+
yield res if block_given?
|
22
|
+
res
|
23
|
+
end
|
24
|
+
|
25
|
+
def exists?(path)
|
26
|
+
@contents.key?(path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def loaded?(path)
|
30
|
+
@contents[path].loaded == true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/inspec/runner.rb
CHANGED
@@ -99,10 +99,7 @@ module Inspec
|
|
99
99
|
|
100
100
|
# load all libraries
|
101
101
|
ctx = create_context(options)
|
102
|
-
libs.
|
103
|
-
ctx.load(lib[:content].to_s, lib[:ref], lib[:line] || 1)
|
104
|
-
ctx.reload_dsl
|
105
|
-
end
|
102
|
+
ctx.load_libraries(libs.map { |x| [x[:content], x[:ref], x[:line]] })
|
106
103
|
|
107
104
|
# hand the context to the profile for further evaluation
|
108
105
|
unless (profile = options['profile']).nil?
|
data/lib/inspec/version.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Dominik Richter
|
3
|
+
# author: Christoph Hartmann
|
4
|
+
|
5
|
+
class HashMap
|
6
|
+
class << self
|
7
|
+
def [](hash, *keys)
|
8
|
+
return hash if keys.empty? || hash.nil?
|
9
|
+
key = keys.shift
|
10
|
+
if hash.is_a?(Array)
|
11
|
+
map = hash.map { |i| [i, key] }
|
12
|
+
else
|
13
|
+
map = hash[key]
|
14
|
+
end
|
15
|
+
[map, *keys]
|
16
|
+
rescue NoMethodError => _
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class StringMap
|
23
|
+
class << self
|
24
|
+
def [](hash, *keys)
|
25
|
+
return hash if keys.empty? || hash.nil?
|
26
|
+
key = keys.shift
|
27
|
+
if hash.is_a?(Array)
|
28
|
+
map = hash.map { |i| [i, key] }
|
29
|
+
else
|
30
|
+
map = hash[key]
|
31
|
+
end
|
32
|
+
[map, *keys]
|
33
|
+
rescue NoMethodError => _
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -105,4 +105,12 @@ describe 'inspec exec' do
|
|
105
105
|
out.stderr.must_equal "This profile requires InSpec version >= 99.0.0. You are running InSpec v#{Inspec::VERSION}.\n"
|
106
106
|
end
|
107
107
|
end
|
108
|
+
|
109
|
+
describe 'with a profile that loads a library and reference' do
|
110
|
+
let(:out) { inspec('exec ' + File.join(profile_path, 'library')) }
|
111
|
+
|
112
|
+
it 'executes the profile without error' do
|
113
|
+
out.exit_status.must_equal 0
|
114
|
+
end
|
115
|
+
end
|
108
116
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
name: complete
|
2
|
+
title: complete example profile
|
3
|
+
maintainer: Chef Software, Inc.
|
4
|
+
copyright: Chef Software, Inc.
|
5
|
+
copyright_email: support@chef.io
|
6
|
+
license: Proprietary, All rights reserved
|
7
|
+
summary: Testing stub
|
8
|
+
version: 1.0.0
|
9
|
+
supports:
|
10
|
+
- os-family: linux
|
@@ -0,0 +1,10 @@
|
|
1
|
+
name: complete
|
2
|
+
title: complete example profile
|
3
|
+
maintainer: Chef Software, Inc.
|
4
|
+
copyright: Chef Software, Inc.
|
5
|
+
copyright_email: support@chef.io
|
6
|
+
license: Proprietary, All rights reserved
|
7
|
+
summary: Testing stub
|
8
|
+
version: 1.0.0
|
9
|
+
supports:
|
10
|
+
- os-family: linux
|
@@ -307,4 +307,39 @@ describe Inspec::ProfileContext do
|
|
307
307
|
end
|
308
308
|
end
|
309
309
|
end
|
310
|
+
|
311
|
+
describe 'library loading' do
|
312
|
+
it 'supports simple ruby require statements' do
|
313
|
+
# Please note: we do discourage the use of Gems in inspec resources at
|
314
|
+
# this time. Resources should be well packaged whenever possible.
|
315
|
+
proc { profile.load('Net::POP3') }.must_raise NameError
|
316
|
+
profile.load_libraries([['require "net/pop"', 'libraries/a.rb']])
|
317
|
+
profile.load('Net::POP3').to_s.must_equal 'Net::POP3'
|
318
|
+
end
|
319
|
+
|
320
|
+
it 'supports loading across the library' do
|
321
|
+
profile.load_libraries([
|
322
|
+
["require 'a'\nA", 'libraries/b.rb'],
|
323
|
+
['module A; end', 'libraries/a.rb']
|
324
|
+
])
|
325
|
+
profile.load('A').to_s.must_equal 'A'
|
326
|
+
end
|
327
|
+
|
328
|
+
it 'fails loading if reference error occur' do
|
329
|
+
proc {
|
330
|
+
profile.load_libraries([
|
331
|
+
["require 'a'\nB", 'libraries/b.rb'],
|
332
|
+
['module A; end', 'libraries/a.rb']
|
333
|
+
])
|
334
|
+
}.must_raise NameError
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'fails loading if a reference dependency isnt found' do
|
338
|
+
proc {
|
339
|
+
profile.load_libraries([
|
340
|
+
["require 'a'\nA", 'libraries/b.rb'],
|
341
|
+
])
|
342
|
+
}.must_raise LoadError
|
343
|
+
end
|
344
|
+
end
|
310
345
|
end
|
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:
|
4
|
+
version: 0.24.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
|
+
date: 2016-06-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: r-train
|
@@ -282,6 +282,7 @@ files:
|
|
282
282
|
- lib/inspec/polyfill.rb
|
283
283
|
- lib/inspec/profile.rb
|
284
284
|
- lib/inspec/profile_context.rb
|
285
|
+
- lib/inspec/require_loader.rb
|
285
286
|
- lib/inspec/resource.rb
|
286
287
|
- lib/inspec/rspec_json_formatter.rb
|
287
288
|
- lib/inspec/rule.rb
|
@@ -359,6 +360,7 @@ files:
|
|
359
360
|
- lib/utils/filter_array.rb
|
360
361
|
- lib/utils/find_files.rb
|
361
362
|
- lib/utils/hash.rb
|
363
|
+
- lib/utils/hash_map.rb
|
362
364
|
- lib/utils/json_log.rb
|
363
365
|
- lib/utils/modulator.rb
|
364
366
|
- lib/utils/object_traversal.rb
|
@@ -551,6 +553,12 @@ files:
|
|
551
553
|
- test/unit/mock/profiles/legacy-empty-metadata/metadata.rb
|
552
554
|
- test/unit/mock/profiles/legacy-simple-metadata/metadata.rb
|
553
555
|
- test/unit/mock/profiles/legacy-simple-metadata/test/.gitkeep
|
556
|
+
- test/unit/mock/profiles/library/controls/filesystem_spec.rb
|
557
|
+
- test/unit/mock/profiles/library/inspec.yml
|
558
|
+
- test/unit/mock/profiles/library/libraries/gordonlib.rb
|
559
|
+
- test/unit/mock/profiles/library/libraries/testlib.rb
|
560
|
+
- test/unit/mock/profiles/resource-tiny/inspec.yml
|
561
|
+
- test/unit/mock/profiles/resource-tiny/libraries/resource.rb
|
554
562
|
- test/unit/mock/profiles/simple-metadata/inspec.yml
|
555
563
|
- test/unit/mock/profiles/skippy-profile-os/controls/one.rb
|
556
564
|
- test/unit/mock/profiles/skippy-profile-os/inspec.yml
|
@@ -639,7 +647,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
639
647
|
version: '0'
|
640
648
|
requirements: []
|
641
649
|
rubyforge_project:
|
642
|
-
rubygems_version: 2.
|
650
|
+
rubygems_version: 2.5.1
|
643
651
|
signing_key:
|
644
652
|
specification_version: 4
|
645
653
|
summary: Infrastructure and compliance testing.
|
@@ -829,6 +837,12 @@ test_files:
|
|
829
837
|
- test/unit/mock/profiles/legacy-empty-metadata/metadata.rb
|
830
838
|
- test/unit/mock/profiles/legacy-simple-metadata/metadata.rb
|
831
839
|
- test/unit/mock/profiles/legacy-simple-metadata/test/.gitkeep
|
840
|
+
- test/unit/mock/profiles/library/controls/filesystem_spec.rb
|
841
|
+
- test/unit/mock/profiles/library/inspec.yml
|
842
|
+
- test/unit/mock/profiles/library/libraries/gordonlib.rb
|
843
|
+
- test/unit/mock/profiles/library/libraries/testlib.rb
|
844
|
+
- test/unit/mock/profiles/resource-tiny/inspec.yml
|
845
|
+
- test/unit/mock/profiles/resource-tiny/libraries/resource.rb
|
832
846
|
- test/unit/mock/profiles/simple-metadata/inspec.yml
|
833
847
|
- test/unit/mock/profiles/skippy-profile-os/controls/one.rb
|
834
848
|
- test/unit/mock/profiles/skippy-profile-os/inspec.yml
|