Class: Inspec::Runner

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/inspec/runner.rb

Overview

Inspec::Runner coordinates the running of tests and is the main entry point to the application.

Users are expected to insantiate a runner, add targets to be run, and then call the run method:

“‘ r = Inspec::Runner.new() r.add_target(“/path/to/some/profile”) r.add_target(“url/to/some/profile”) r.run “`

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(conf = {}) ⇒ Runner

Returns a new instance of Runner.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/inspec/runner.rb', line 38

def initialize(conf = {})
  @rules = []
  @conf = conf.dup
  @conf[:logger] ||= Logger.new(nil)
  @target_profiles = []
  @controls = @conf[:controls] || []
  @ignore_supports = @conf[:ignore_supports]

  @test_collector = @conf.delete(:test_collector) || begin
    require 'inspec/runner_rspec'
    RunnerRspec.new(@conf)
  end

  # list of profile attributes
  @attributes = []

  load_attributes(@conf)
  configure_transport
end

Instance Attribute Details

#attributesObject (readonly)

Returns the value of attribute attributes.



37
38
39
# File 'lib/inspec/runner.rb', line 37

def attributes
  @attributes
end

#backendObject (readonly)

Returns the value of attribute backend.



37
38
39
# File 'lib/inspec/runner.rb', line 37

def backend
  @backend
end

#rulesObject (readonly)

Returns the value of attribute rules.



37
38
39
# File 'lib/inspec/runner.rb', line 37

def rules
  @rules
end

Instance Method Details

#add_target(target, _opts = []) ⇒ Object

add_target allows the user to add a target whose tests will be run when the user calls the run method.

A target is a path or URL that points to a profile. Using this target we generate a Profile and a ProfileContext. The content (libraries, tests, and attributes) from the Profile are loaded into the ProfileContext.

If the profile depends on other profiles, those profiles will be loaded on-demand when include_content or required_content are called using similar code in Inspec::DSL.

Once the we’ve loaded all of the tests files in the profile, we query the profile for the full list of rules. Those rules are registered with the @test_collector which is ultimately responsible for actually running the tests.

TODO: Deduplicate/clarify the loading code that exists in here, the ProfileContext, the Profile, and Inspec::DSL



128
129
130
131
132
133
134
135
# File 'lib/inspec/runner.rb', line 128

def add_target(target, _opts = [])
  profile = Inspec::Profile.for_target(target,
                                       backend: @backend,
                                       controls: @controls,
                                       attributes: @conf[:attributes])
  fail "Could not resolve #{target} to valid input." if profile.nil?
  @target_profiles << profile if supports_profile?(profile)
end

#all_rulesObject

In some places we read the rules off of the runner, in other places we read it off of the profile context. To keep the API’s the same, we provide an #all_rules method here as well.



171
172
173
# File 'lib/inspec/runner.rb', line 171

def all_rules
  @rules
end

#configure_transportObject



62
63
64
65
# File 'lib/inspec/runner.rb', line 62

def configure_transport
  @backend = Inspec::Backend.create(@conf)
  @test_collector.backend = @backend
end

#create_context(options = {}) ⇒ Object

This is used by inspec-shell and inspec-detect. This should probably be cleaned up a bit.



144
145
146
147
148
149
# File 'lib/inspec/runner.rb', line 144

def create_context(options = {})
  meta = options[:metadata]
  profile_id = nil
  profile_id = meta.params[:name] unless meta.nil?
  Inspec::ProfileContext.new(profile_id, @backend, @conf.merge(options))
end

#load_attributes(options) ⇒ Object

determine all attributes before the execution, fetch data from secrets backend



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/inspec/runner.rb', line 88

def load_attributes(options)
  attributes = {}
  # read endpoints for secrets eg. yml file
  secrets_targets = options['attrs']
  unless secrets_targets.nil?
    secrets_targets.each do |target|
      secrets = Inspec::SecretsBackend.resolve(target)
      # merge hash values
      attributes = attributes.merge(secrets.attributes) unless secrets.nil? || secrets.attributes.nil?
    end
  end
  options['attributes'] = attributes
end

#register_rules(ctx) ⇒ Object



175
176
177
178
179
180
181
182
183
# File 'lib/inspec/runner.rb', line 175

def register_rules(ctx)
  new_tests = false
  ctx.rules.each do |rule_id, rule|
    next if block_given? && !(yield rule_id, rule)
    new_tests = true
    register_rule(rule)
  end
  new_tests
end

#run(with = nil) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/inspec/runner.rb', line 67

def run(with = nil)
  Inspec::Log.debug "Starting run with targets: #{@target_profiles.map(&:to_s)}"
  Inspec::Log.debug "Backend is #{@backend}"
  all_controls = []

  @target_profiles.each do |profile|
    @test_collector.add_profile(profile)
    profile.locked_dependencies
    profile.load_libraries
    @attributes |= profile.runner_context.attributes
    all_controls += profile.collect_tests
  end

  all_controls.each do |rule|
    register_rule(rule)
  end

  @test_collector.run(with)
end

#supports_profile?(profile) ⇒ Boolean

Returns:

  • (Boolean)


151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/inspec/runner.rb', line 151

def supports_profile?(profile)
  return true if profile..nil? || @ignore_supports

  if !profile..supports_runtime?
    fail 'This profile requires InSpec version '\
         "#{profile..inspec_requirement}. You are running "\
         "InSpec v#{Inspec::VERSION}.\n"
  end

  if !profile..supports_transport?(@backend)
    os_info = @backend.os[:name].to_s
    fail "This OS/platform (#{os_info}) is not supported by this profile."
  end

  true
end

#testsObject



58
59
60
# File 'lib/inspec/runner.rb', line 58

def tests
  @test_collector.tests
end