inspec 0.23 → 0.24.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8531472157b9bbcf1f5cfae47afb58e26768955d
4
- data.tar.gz: e11d0a1081f017dedb9a5c207790d6c599286058
3
+ metadata.gz: cdee2bef2b5cae85b1427243ae5013641ec00de9
4
+ data.tar.gz: ff0b32c16345ee013475a10254c52afc1780e49e
5
5
  SHA512:
6
- metadata.gz: ba616285cc0d78bd09a257367933ec1b16ce53c4ef8db770cf5a8a3885ff7fd885589d1b568982bfa0d5fe76d30cacebece6f40622a9e6d66e116759b608b0ad
7
- data.tar.gz: 91e3dfc02e260cef1c4d0b518717b40c6068b225748bb8a26f263a709cfd4ea9d60ec5d9e52fcd11e608a31dafe389888ab94cb15ff3838edaef6030693364cd
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.23](https://github.com/chef/inspec/tree/0.23) (2016-05-31)
4
- [Full Changelog](https://github.com/chef/inspec/compare/v0.22.1...0.23)
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 eq '/^1$/' }
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 eq '/RC/' }
643
- its('stdout') { should_not eq '/DEVEL/' }
644
- its('stdout') { should_not eq '/BETA/' }
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.each do |lib|
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?
@@ -3,5 +3,5 @@
3
3
  # author: Christoph Hartmann
4
4
 
5
5
  module Inspec
6
- VERSION = '0.23'.freeze
6
+ VERSION = '0.24.0'.freeze
7
7
  end
@@ -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,7 @@
1
+ # encoding: utf-8
2
+ # copyright: 2015, Chef Software, Inc
3
+ # license: All rights reserved
4
+
5
+ describe gordon do
6
+ it { should be_enabled }
7
+ 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,2 @@
1
+ module GordonLib
2
+ end
@@ -0,0 +1,12 @@
1
+ # Library resource
2
+
3
+ require 'gordonlib'
4
+ require 'hashie'
5
+
6
+ class Gordon < Inspec.resource(1)
7
+ name 'gordon'
8
+ include GordonLib
9
+ def enabled?
10
+ true
11
+ end
12
+ 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,3 @@
1
+ class Tiny < Inspec.resource(1)
2
+ name 'tiny'
3
+ end
@@ -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: '0.23'
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-05-31 00:00:00.000000000 Z
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.4.6
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