Class: Inspec::Runner

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

Overview

rubocop:disable Metrics/ClassLength

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(conf = {}) ⇒ Runner

Returns a new instance of Runner.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/inspec/runner.rb', line 20

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

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



19
20
21
# File 'lib/inspec/runner.rb', line 19

def attributes
  @attributes
end

#backendObject (readonly)

Returns the value of attribute backend.



19
20
21
# File 'lib/inspec/runner.rb', line 19

def backend
  @backend
end

#rulesObject (readonly)

Returns the value of attribute rules.



19
20
21
# File 'lib/inspec/runner.rb', line 19

def rules
  @rules
end

Instance Method Details

#add_content(tests, libs, options = {}) ⇒ Object

Returns the profile context used to evaluate the given content. Calling this method again will use a different context each time.



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/inspec/runner.rb', line 122

def add_content(tests, libs, options = {})
  return if tests.nil? || tests.empty?

  # load all libraries
  ctx = create_context(options)
  ctx.load_libraries(libs.map { |x| [x[:content], x[:ref], x[:line]] })

  # hand the context to the profile for further evaluation
  unless (profile = options[:profile]).nil?
    profile.runner_context = ctx
  end

  # evaluate the test content
  Array(tests).each { |t| add_test_to_context(t, ctx) }

  # merge and collect all attributes
  @attributes |= ctx.attributes

  # process the resulting rules
  filter_controls(ctx.all_rules, options[:controls]).each do |rule|
    register_rule(rule)
  end

  ctx
end

#add_profile(profile, options = {}) ⇒ Object

Returns the profile context used to initialize this profile.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/inspec/runner.rb', line 94

def add_profile(profile, options = {})
  return if !options[:ignore_supports] && !supports_profile?(profile)

  @test_collector.add_profile(profile)
  options[:metadata] = profile.
  options[:profile] = profile

  libs = profile.libraries.map do |k, v|
    { ref: k, content: v }
  end

  tests = profile.tests.map do |ref, content|
    r = profile.source_reader.target.abs_path(ref)
    { ref: r, content: content }
  end

  add_content(tests, libs, options)
end

#add_target(target, options = {}) ⇒ Object

Returns the profile context used the profile at this target.



70
71
72
73
74
# File 'lib/inspec/runner.rb', line 70

def add_target(target, options = {})
  profile = Inspec::Profile.for_target(target, options)
  fail "Could not resolve #{target} to valid input." if profile.nil?
  add_profile(profile, options)
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.



151
152
153
# File 'lib/inspec/runner.rb', line 151

def all_rules
  @rules
end

#configure_transportObject



49
50
51
52
# File 'lib/inspec/runner.rb', line 49

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

#create_context(options = {}) ⇒ Object



113
114
115
116
117
118
# File 'lib/inspec/runner.rb', line 113

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



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/inspec/runner.rb', line 55

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

#normalize_map(hm) ⇒ Object



41
42
43
44
45
46
47
# File 'lib/inspec/runner.rb', line 41

def normalize_map(hm)
  res = {}
  hm.each {|k, v|
    res[k.to_s] = v
  }
  res
end

#register_rules(ctx) ⇒ Object



155
156
157
158
159
160
161
162
163
# File 'lib/inspec/runner.rb', line 155

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

#supports_profile?(profile) ⇒ Boolean

Returns:

  • (Boolean)


76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/inspec/runner.rb', line 76

def supports_profile?(profile)
  return true if profile..nil?

  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



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

def tests
  @test_collector.tests
end