inspec 0.24.0 → 0.25.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: 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