inspec 0.24.0 → 0.25.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: cdee2bef2b5cae85b1427243ae5013641ec00de9
4
- data.tar.gz: ff0b32c16345ee013475a10254c52afc1780e49e
3
+ metadata.gz: ee0308ac7f5c85399e7ad0a3854ff85bbc94d765
4
+ data.tar.gz: 85d09ad742b7744f075b8aa8326192d6fc09cc35
5
5
  SHA512:
6
- metadata.gz: 0e54f5100590735780ec9815a570f7171c3297a2747c9dbd7c40d7c8fe099acd36000ee74cd05e1269ea4ebb2b06276dc46f0c551547da2a3060b7aa861d7cb3
7
- data.tar.gz: eb40755a53b7e4f9d5fa264b92a778829833835ca77d81a8ba91b59fb0b057f6a7981a47ab87336832bed17b691c2b13d70594a83c83d08a83f1b1770ed75716
6
+ metadata.gz: db34bc62e3bb9789ed7974617814a5249ff4ebc0175e70275b87b398bc2ffc47c63ac665d6ee1ac34059c4041c7a0dc57c1a57b1913a9e2e4893d34ecaf0cad4
7
+ data.tar.gz: d7490e64740e145aa8fafeb1d821988d841c7d05542ba1fa73a57f88f171b5bf349c961140c04804344b9edaeecfa5e08609e2b50b033d4e794df6fdf8ba28b0
@@ -1,7 +1,19 @@
1
1
  # Change Log
2
2
 
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)
3
+ ## [0.25.0](https://github.com/chef/inspec/tree/0.25.0) (2016-06-14)
4
+ [Full Changelog](https://github.com/chef/inspec/compare/v0.24.0...0.25.0)
5
+
6
+ **Closed issues:**
7
+
8
+ - Why mode matcher doesn't work on a file resource [\#781](https://github.com/chef/inspec/issues/781)
9
+
10
+ **Merged pull requests:**
11
+
12
+ - Update readme with Annie's Tutorial Day 5 [\#785](https://github.com/chef/inspec/pull/785) ([anniehedgpeth](https://github.com/anniehedgpeth))
13
+ - Feature: Implementation of RFC Attributes [\#723](https://github.com/chef/inspec/pull/723) ([chris-rock](https://github.com/chris-rock))
14
+
15
+ ## [v0.24.0](https://github.com/chef/inspec/tree/v0.24.0) (2016-06-03)
16
+ [Full Changelog](https://github.com/chef/inspec/compare/v0.23...v0.24.0)
5
17
 
6
18
  **Implemented enhancements:**
7
19
 
data/README.md CHANGED
@@ -222,6 +222,7 @@ Blogs:
222
222
  * [InSpec Tutorial: Day 2 - Command Resource Blog Logo](http://www.anniehedgie.com/inspec-basics-2)
223
223
  * [InSpec Tutorial: Day 3 - File Resource](http://www.anniehedgie.com/inspec-basics-3)
224
224
  * [InSpec Tutorial: Day 4 - Custom Matchers](http://www.anniehedgie.com/inspec-basics-4)
225
+ * [InSpec Tutorial: Day 5 - Creating a Profile](http://www.anniehedgie.com/inspec-basics-5)
225
226
  * [Windows infrastructure testing using InSpec – Part I](http://datatomix.com/?p=236)
226
227
  * [Windows infrastructure testing using InSpec and Profiles – Part II](http://datatomix.com/?p=238)
227
228
  * [Testing Ansible with Inspec](http://scienceofficersblog.blogspot.de/2016/02/testing-ansible-with-inspec.html)
@@ -0,0 +1,2 @@
1
+ user: bob
2
+ password: secret
@@ -0,0 +1,14 @@
1
+ # Example InSpec Profile with Attributes
2
+
3
+ This profile uses InSpec attributes to parameterize a profile.
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ $ inspec exec examples/profile-attribute --attrs examples/profile-attribute.yml
9
+ ....
10
+
11
+ Finished in 0.00178 seconds (files took 0.48529 seconds to load)
12
+ 4 examples, 0 failures
13
+
14
+ ```
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ val_user = attribute('user', default: 'alice', description: 'An identification for the user')
3
+ val_password = attribute('password', description: 'A value for the password')
4
+
5
+ describe val_user do
6
+ it { should eq 'bob' }
7
+ end
8
+
9
+ describe val_password do
10
+ it { should eq 'secret' }
11
+ end
@@ -0,0 +1,8 @@
1
+ name: profile-attribute
2
+ title: InSpec Profile
3
+ maintainer: The Authors
4
+ copyright: The Authors
5
+ copyright_email: you@example.com
6
+ license: All Rights Reserved
7
+ summary: An InSpec Compliance Profile
8
+ version: 0.1.0
@@ -108,7 +108,10 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
108
108
  exec_options
109
109
  def exec(*targets)
110
110
  diagnose
111
- run_tests(targets, opts)
111
+ o = opts.dup
112
+
113
+ # run tests
114
+ run_tests(targets, o)
112
115
  end
113
116
 
114
117
  desc 'detect', 'detect the target OS'
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Inspec
4
+ autoload :Attribute, 'inspec/objects/attribute'
4
5
  autoload :Control, 'inspec/objects/control'
5
6
  autoload :EachLoop, 'inspec/objects/each_loop'
6
7
  autoload :List, 'inspec/objects/list'
@@ -0,0 +1,35 @@
1
+ # encoding:utf-8
2
+
3
+ module Inspec
4
+ class Attribute
5
+ attr_accessor :name
6
+ def initialize(name, options)
7
+ @name = name
8
+ @opts = options
9
+ @value = nil
10
+ end
11
+
12
+ # implicit call is done by inspec to determine the value of an attribute
13
+ def value(newvalue = nil)
14
+ unless newvalue.nil?
15
+ @value = newvalue
16
+ end
17
+ @value || default
18
+ end
19
+
20
+ def default
21
+ @opts[:default]
22
+ end
23
+
24
+ def to_hash
25
+ {
26
+ name: @name,
27
+ options: @opts,
28
+ }
29
+ end
30
+
31
+ def to_s
32
+ "Attribute #{@name} with #{@value}"
33
+ end
34
+ end
35
+ end
@@ -11,6 +11,7 @@ module Inspec
11
11
  autoload :CLI, 'inspec/plugins/cli'
12
12
  autoload :Fetcher, 'inspec/plugins/fetcher'
13
13
  autoload :SourceReader, 'inspec/plugins/source_reader'
14
+ autoload :Secret, 'inspec/plugins/secret'
14
15
  end
15
16
 
16
17
  # PLEASE NOTE: The Plugin system is an internal mechanism for connecting
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ require 'utils/plugin_registry'
6
+
7
+ module Inspec
8
+ module Plugins
9
+ class Secret < PluginRegistry::Plugin
10
+ def self.plugin_registry
11
+ Inspec::SecretsBackend
12
+ end
13
+ end
14
+ end
15
+ end
@@ -57,6 +57,7 @@ module Inspec
57
57
 
58
58
  def info
59
59
  res = params.dup
60
+ # add information about the controls
60
61
  controls = res[:controls].map do |id, rule|
61
62
  next if id.to_s.empty?
62
63
  data = rule.dup
@@ -67,6 +68,9 @@ module Inspec
67
68
  [id, data]
68
69
  end
69
70
  res[:controls] = Hash[controls.compact]
71
+
72
+ # add information about the required attributes
73
+ res[:attributes] = res[:attributes].map(&:to_hash) unless res[:attributes].nil? || res[:attributes].empty?
70
74
  res
71
75
  end
72
76
 
@@ -248,13 +252,16 @@ module Inspec
248
252
  f = load_rule_filepath(prefix, rule)
249
253
  load_rule(rule, f, controls, groups)
250
254
  end
255
+ params[:attributes] = runner.attributes
251
256
  else
252
257
  # load from context
253
258
  @runner_context.rules.values.each do |rule|
254
259
  f = load_rule_filepath(prefix, rule)
255
260
  load_rule(rule, f, controls, groups)
256
261
  end
262
+ params[:attributes] = @runner_context.attributes
257
263
  end
264
+ params
258
265
  end
259
266
 
260
267
  def load_rule_filepath(prefix, rule)
@@ -6,10 +6,12 @@ require 'inspec/rule'
6
6
  require 'inspec/dsl'
7
7
  require 'inspec/require_loader'
8
8
  require 'securerandom'
9
+ require 'inspec/objects/attribute'
9
10
 
10
11
  module Inspec
11
12
  class ProfileContext # rubocop:disable Metrics/ClassLength
12
13
  attr_reader :rules
14
+ attr_reader :attributes
13
15
  def initialize(profile_id, backend, conf)
14
16
  if backend.nil?
15
17
  fail 'ProfileContext is initiated with a backend == nil. ' \
@@ -21,7 +23,7 @@ module Inspec
21
23
  @conf = conf.dup
22
24
  @rules = {}
23
25
  @require_loader = ::Inspec::RequireLoader.new
24
-
26
+ @attributes = []
25
27
  reload_dsl
26
28
  end
27
29
 
@@ -84,6 +86,15 @@ module Inspec
84
86
  end
85
87
  end
86
88
 
89
+ def register_attribute(name, options = {})
90
+ # we need to return an attribute object, to allow dermination of default values
91
+ attr = Attribute.new(name, options)
92
+ # read value from given gived values
93
+ attr.value(@conf['attributes'][attr.name]) unless @conf['attributes'].nil?
94
+ @attributes.push(attr)
95
+ attr.value
96
+ end
97
+
87
98
  def set_header(field, val)
88
99
  @current_load[field] = val
89
100
  end
@@ -180,9 +191,9 @@ module Inspec
180
191
  profile_context_owner.register_rule(control, &block) unless control.nil?
181
192
  end
182
193
 
183
- # TODO: mock method for attributes; import attribute handling
184
- define_method :attributes do |_name, _options|
185
- nil
194
+ # method for attributes; import attribute handling
195
+ define_method :attribute do |name, options|
196
+ profile_context_owner.register_attribute(name, options)
186
197
  end
187
198
 
188
199
  define_method :skip_control do |id|
@@ -10,12 +10,13 @@ require 'inspec/backend'
10
10
  require 'inspec/profile_context'
11
11
  require 'inspec/profile'
12
12
  require 'inspec/metadata'
13
+ require 'inspec/secrets'
13
14
  # spec requirements
14
15
 
15
16
  module Inspec
16
17
  class Runner # rubocop:disable Metrics/ClassLength
17
18
  extend Forwardable
18
- attr_reader :backend, :rules
19
+ attr_reader :backend, :rules, :attributes
19
20
  def initialize(conf = {})
20
21
  @rules = {}
21
22
  @conf = conf.dup
@@ -26,6 +27,10 @@ module Inspec
26
27
  RunnerRspec.new(@conf)
27
28
  end
28
29
 
30
+ # list of profile attributes
31
+ @attributes = []
32
+
33
+ load_attributes(@conf)
29
34
  configure_transport
30
35
  end
31
36
 
@@ -45,6 +50,21 @@ module Inspec
45
50
  @backend = Inspec::Backend.create(@conf)
46
51
  end
47
52
 
53
+ # determine all attributes before the execution, fetch data from secrets backend
54
+ def load_attributes(options)
55
+ attributes = {}
56
+ # read endpoints for secrets eg. yml file
57
+ secrets_targets = options['attrs']
58
+ unless secrets_targets.nil?
59
+ secrets_targets.each do |target|
60
+ secrets = Inspec::SecretsBackend.resolve(target)
61
+ # merge hash values
62
+ attributes = attributes.merge(secrets.attributes) unless secrets.nil? || secrets.attributes.nil?
63
+ end
64
+ end
65
+ options['attributes'] = attributes
66
+ end
67
+
48
68
  def add_target(target, options = {})
49
69
  profile = Inspec::Profile.for_target(target, options)
50
70
  fail "Could not resolve #{target} to valid input." if profile.nil?
@@ -110,6 +130,9 @@ module Inspec
110
130
  tests = [tests] unless tests.is_a? Array
111
131
  tests.each { |t| add_test_to_context(t, ctx) }
112
132
 
133
+ # merge all collect all attributes
134
+ @attributes |= ctx.attributes
135
+
113
136
  # process the resulting rules
114
137
  filter_controls(ctx.rules, options[:controls]).each do |rule_id, rule|
115
138
  register_rule(rule_id, rule)
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ # author: Christoph Hartmann
3
+ # author: Dominik Richter
4
+
5
+ require 'inspec/plugins'
6
+ require 'utils/plugin_registry'
7
+
8
+ module Inspec
9
+ SecretsBackend = PluginRegistry.new
10
+
11
+ def self.secrets(version)
12
+ if version != 1
13
+ fail 'Only secrets version 1 is supported!'
14
+ end
15
+ Inspec::Plugins::Secret
16
+ end
17
+ end
18
+
19
+ require 'inspec/secrets/yaml'
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+
5
+ module Secrets
6
+ class YAML < Inspec.secrets(1)
7
+ name 'yaml'
8
+
9
+ attr_reader :attributes
10
+
11
+ def self.resolve(target)
12
+ unless target.is_a?(String) && File.file?(target) && target.end_with?('.yml')
13
+ return nil
14
+ end
15
+ new(target)
16
+ end
17
+
18
+ # array of yaml file paths
19
+ def initialize(target)
20
+ @attributes = ::YAML.load_file(target)
21
+ end
22
+ end
23
+ end
@@ -3,5 +3,5 @@
3
3
  # author: Christoph Hartmann
4
4
 
5
5
  module Inspec
6
- VERSION = '0.24.0'.freeze
6
+ VERSION = '0.25.0'.freeze
7
7
  end
@@ -55,6 +55,8 @@ module Inspec
55
55
  desc: 'Which formatter to use: progress, documentation, json'
56
56
  option :color, type: :boolean, default: true,
57
57
  desc: 'Use colors in output.'
58
+ option :attrs, type: :array,
59
+ desc: 'Load attributes file (experimental)'
58
60
  end
59
61
 
60
62
  private
@@ -39,7 +39,6 @@ describe 'inspec exec with json formatter' do
39
39
  actual = profile.dup
40
40
  key = actual.delete('controls').keys
41
41
  .find { |x| x =~ /generated from example.rb/ }
42
-
43
42
  actual.must_equal({
44
43
  "name" => "profile",
45
44
  "title" => "InSpec Example Profile",
@@ -55,6 +54,7 @@ describe 'inspec exec with json formatter' do
55
54
  "controls/example.rb" => {"title"=>"/tmp profile", "controls"=>["tmp-1.0", key]},
56
55
  "controls/gordon.rb" => {"title"=>"Gordon Config Checks", "controls"=>["gordon-1.0"]},
57
56
  },
57
+ "attributes" => []
58
58
  })
59
59
  end
60
60
 
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.24.0
4
+ version: 0.25.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-06-03 00:00:00.000000000 Z
11
+ date: 2016-06-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: r-train
@@ -220,6 +220,10 @@ files:
220
220
  - examples/kitchen-puppet/manifests/site.pp
221
221
  - examples/kitchen-puppet/metadata.json
222
222
  - examples/kitchen-puppet/test/integration/default/web_spec.rb
223
+ - examples/profile-attribute.yml
224
+ - examples/profile-attribute/README.md
225
+ - examples/profile-attribute/controls/example.rb
226
+ - examples/profile-attribute/inspec.yml
223
227
  - examples/profile/README.md
224
228
  - examples/profile/controls/example.rb
225
229
  - examples/profile/controls/gordon.rb
@@ -267,6 +271,7 @@ files:
267
271
  - lib/inspec/log.rb
268
272
  - lib/inspec/metadata.rb
269
273
  - lib/inspec/objects.rb
274
+ - lib/inspec/objects/attribute.rb
270
275
  - lib/inspec/objects/control.rb
271
276
  - lib/inspec/objects/each_loop.rb
272
277
  - lib/inspec/objects/list.rb
@@ -278,6 +283,7 @@ files:
278
283
  - lib/inspec/plugins/cli.rb
279
284
  - lib/inspec/plugins/fetcher.rb
280
285
  - lib/inspec/plugins/resource.rb
286
+ - lib/inspec/plugins/secret.rb
281
287
  - lib/inspec/plugins/source_reader.rb
282
288
  - lib/inspec/polyfill.rb
283
289
  - lib/inspec/profile.rb
@@ -289,6 +295,8 @@ files:
289
295
  - lib/inspec/runner.rb
290
296
  - lib/inspec/runner_mock.rb
291
297
  - lib/inspec/runner_rspec.rb
298
+ - lib/inspec/secrets.rb
299
+ - lib/inspec/secrets/yaml.rb
292
300
  - lib/inspec/shell.rb
293
301
  - lib/inspec/source_reader.rb
294
302
  - lib/inspec/version.rb
@@ -360,7 +368,6 @@ files:
360
368
  - lib/utils/filter_array.rb
361
369
  - lib/utils/find_files.rb
362
370
  - lib/utils/hash.rb
363
- - lib/utils/hash_map.rb
364
371
  - lib/utils/json_log.rb
365
372
  - lib/utils/modulator.rb
366
373
  - lib/utils/object_traversal.rb
@@ -557,8 +564,6 @@ files:
557
564
  - test/unit/mock/profiles/library/inspec.yml
558
565
  - test/unit/mock/profiles/library/libraries/gordonlib.rb
559
566
  - 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
562
567
  - test/unit/mock/profiles/simple-metadata/inspec.yml
563
568
  - test/unit/mock/profiles/skippy-profile-os/controls/one.rb
564
569
  - test/unit/mock/profiles/skippy-profile-os/inspec.yml
@@ -647,7 +652,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
647
652
  version: '0'
648
653
  requirements: []
649
654
  rubyforge_project:
650
- rubygems_version: 2.5.1
655
+ rubygems_version: 2.4.6
651
656
  signing_key:
652
657
  specification_version: 4
653
658
  summary: Infrastructure and compliance testing.
@@ -841,8 +846,6 @@ test_files:
841
846
  - test/unit/mock/profiles/library/inspec.yml
842
847
  - test/unit/mock/profiles/library/libraries/gordonlib.rb
843
848
  - 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
846
849
  - test/unit/mock/profiles/simple-metadata/inspec.yml
847
850
  - test/unit/mock/profiles/skippy-profile-os/controls/one.rb
848
851
  - test/unit/mock/profiles/skippy-profile-os/inspec.yml
@@ -1,37 +0,0 @@
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
@@ -1,10 +0,0 @@
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
@@ -1,3 +0,0 @@
1
- class Tiny < Inspec.resource(1)
2
- name 'tiny'
3
- end