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 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