Class: Inspec::ProfileContext

Inherits:
Object
  • Object
show all
Defined in:
lib/inspec/profile_context.rb

Defined Under Namespace

Modules: DomainSpecificLunacy

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(profile_id, backend, conf) ⇒ ProfileContext

Returns a new instance of ProfileContext.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/inspec/profile_context.rb', line 19

def initialize(profile_id, backend, conf)
  if backend.nil?
    raise "ProfileContext is initiated with a backend == nil. " \
         "This is a backend error which must be fixed upstream."
  end
  @profile_id = profile_id
  @backend = backend
  @conf = conf.dup
  @profile_name = @conf.key?("profile") ? @conf["profile"].profile_name : @profile_id
  @skip_only_if_eval = @conf["check_mode"]
  @rules = {}
  @control_subcontexts = []
  @lib_subcontexts = []
  @require_loader = ::Inspec::RequireLoader.new
  Inspec::InputRegistry.register_profile_alias(@profile_id, @profile_name) if @profile_id != @profile_name
  # TODO: consider polling input source plugins; this is a bulk fetch opportunity

  # A local resource registry that only contains resources defined
  # in the transitive dependency tree of the loaded profile.
  @resource_registry = Inspec::Resource.new_registry
  @library_eval_context = Inspec::LibraryEvalContext.create(@resource_registry, @require_loader)
  @current_load = nil
end

Instance Attribute Details

#backendObject (readonly)

Returns the value of attribute backend.



17
18
19
# File 'lib/inspec/profile_context.rb', line 17

def backend
  @backend
end

#current_loadObject (readonly)

Returns the value of attribute current_load.



192
193
194
# File 'lib/inspec/profile_context.rb', line 192

def current_load
  @current_load
end

#library_eval_contextObject (readonly)

Returns the value of attribute library_eval_context.



16
17
18
# File 'lib/inspec/profile_context.rb', line 16

def library_eval_context
  @library_eval_context
end

#profile_idObject (readonly)

Returns the value of attribute profile_id.



17
18
19
# File 'lib/inspec/profile_context.rb', line 17

def profile_id
  @profile_id
end

#profile_nameObject (readonly)

Returns the value of attribute profile_name.



17
18
19
# File 'lib/inspec/profile_context.rb', line 17

def profile_name
  @profile_name
end

#resource_registryObject (readonly)

Returns the value of attribute resource_registry.



17
18
19
# File 'lib/inspec/profile_context.rb', line 17

def resource_registry
  @resource_registry
end

#rulesObject

Returns the value of attribute rules.



18
19
20
# File 'lib/inspec/profile_context.rb', line 18

def rules
  @rules
end

Class Method Details

.for_profile(profile, backend) ⇒ Object



12
13
14
# File 'lib/inspec/profile_context.rb', line 12

def self.for_profile(profile, backend)
  new(profile.name, backend, { "profile" => profile, "check_mode" => profile.check_mode })
end

Instance Method Details

#add_resources(context) ⇒ Object



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

def add_resources(context)
  @resource_registry.merge!(context.resource_registry)
  control_eval_context.add_resources(context)
  @lib_subcontexts << context
  reload_dsl
end

#add_subcontext(context) ⇒ Object



120
121
122
# File 'lib/inspec/profile_context.rb', line 120

def add_subcontext(context)
  @control_subcontexts << context
end

#all_controlsObject Also known as: all_rules



94
95
96
97
98
# File 'lib/inspec/profile_context.rb', line 94

def all_controls
  ret = @rules.values.compact
  ret += @control_subcontexts.map(&:all_rules).flatten
  ret
end

#attributesObject



43
44
45
# File 'lib/inspec/profile_context.rb', line 43

def attributes
  Inspec::AttributeRegistry.list_attributes_for_profile(@profile_id)
end

#control_eval_contextObject



59
60
61
62
63
64
65
66
67
68
# File 'lib/inspec/profile_context.rb', line 59

def control_eval_context
  @control_eval_context ||=
    Inspec::ControlEvalContext.new(self,
                                   to_resources_dsl,
                                   @backend,
                                   @conf,
                                   dependencies,
                                   @require_loader,
                                   @skip_only_if_eval)
end

#dependenciesObject



47
48
49
50
51
52
53
# File 'lib/inspec/profile_context.rb', line 47

def dependencies
  if @conf["profile"].nil?
    {}
  else
    @conf["profile"].locked_dependencies
  end
end

#load_control_file(*args) ⇒ Object Also known as: load



162
163
164
165
166
# File 'lib/inspec/profile_context.rb', line 162

def load_control_file(*args)
  # Set `skip_file` to `false` between file loads to prevent skips from spanning multiple control files
  control_eval_context.skip_file = false
  load_with_context(control_eval_context, *args)
end

#load_libraries(libs) ⇒ Object

Expects arrays of arrays of [[content, path, line]]



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/inspec/profile_context.rb', line 125

def load_libraries(libs)
  lib_prefix = "libraries" + File::SEPARATOR
  autoloads = []

  libs.sort_by! { |l| l[1] } # Sort on source path so load order is deterministic
  libs.each do |content, source, line|
    next unless source.end_with?(".rb")

    path = source
    # Create a list of files (presumably resources) to autoload by stripping the prefixes
    # InSpec < 6: libraries/*.rb
    # In InSpec 7, libraries can be installed under (for example)
    # lib/inspec-test-resources/resources/demo_resource.rb

    if source.start_with?(lib_prefix)
      path = source.sub(lib_prefix, "")
      no_subdir = File.dirname(path) == "."

      autoloads.push(path) if no_subdir
    elsif source.match(%r{^lib/.+/resources/.*\.rb})
      # Gem Resource Pack
      path = source.sub(%r{^lib/}, "")
      autoloads.push(path)
    end

    @require_loader.add(path, content, source, line)
  end

  # load all files directly that are flat inside the libraries folder
  autoloads.each do |path|
    load_library_file(*@require_loader.load(path)) unless
      @require_loader.loaded?(path)
  end

  reload_dsl
end

#load_library_file(*args) ⇒ Object



169
170
171
# File 'lib/inspec/profile_context.rb', line 169

def load_library_file(*args)
  load_with_context(@library_eval_context, *args)
end

#load_with_context(context, content, source = nil, line = nil) ⇒ Object



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

def load_with_context(context, content, source = nil, line = nil)
  Inspec::Log.debug("Loading #{source || "<anonymous content>"} into #{self}")
  @current_load = { file: source }
  if content.is_a? Proc
    context.instance_eval(&content)
  elsif source.nil? && line.nil?
    context.instance_eval(content)
  else
    context.instance_eval(content, source || "unknown", line || 1)
  end
end

#profile_supports_inspec_version?Boolean

Returns:

  • (Boolean)


81
82
83
84
85
# File 'lib/inspec/profile_context.rb', line 81

def profile_supports_inspec_version?
  return true if @conf["profile"].nil?

  @conf["profile"].supports_runtime?
end

#profile_supports_platform?Boolean

Returns:

  • (Boolean)


75
76
77
78
79
# File 'lib/inspec/profile_context.rb', line 75

def profile_supports_platform?
  return true if @conf["profile"].nil?

  @conf["profile"].supports_platform?
end

#register_rule(r) ⇒ Object



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/inspec/profile_context.rb', line 194

def register_rule(r)
  # get the full ID
  file = if @current_load.nil?
           "unknown"
         else
           @current_load[:file] || "unknown"
         end
  r.instance_variable_set(:@__file, file)
  r.instance_variable_set(:@__group_title, current_load[:title])

  # add the rule to the registry
  fid = full_id(Inspec::Rule.profile_id(r), Inspec::Rule.rule_id(r))
  existing = @rules[fid]
  if existing.nil?
    @rules[fid] = r
  else
    Inspec::Rule.merge(existing, r)
  end
end

#reload_dslObject



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

def reload_dsl
  @resource_registry.merge!(Inspec::Resource.new_registry)
  @control_eval_context = nil
end

#remove_rule(id) ⇒ Object



87
88
89
90
91
92
# File 'lib/inspec/profile_context.rb', line 87

def remove_rule(id)
  @rules[id] = nil if @rules.key?(id)
  @control_subcontexts.each do |c|
    c.remove_rule(id)
  end
end

#set_header(field, val) ⇒ Object



214
215
216
# File 'lib/inspec/profile_context.rb', line 214

def set_header(field, val)
  @current_load[field] = val
end

#subcontext_by_name(name) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
# File 'lib/inspec/profile_context.rb', line 101

def subcontext_by_name(name)
  found = @lib_subcontexts.find { |c| c.profile_id == name }
  unless found
    @lib_subcontexts.each do |c|
      found = c.subcontext_by_name(name)
      break if found
    end
  end

  found
end

#to_resources_dslObject



55
56
57
# File 'lib/inspec/profile_context.rb', line 55

def to_resources_dsl
  DomainSpecificLunacy.create_dsl(self)
end

#unregister_rule(id) ⇒ Object



185
186
187
188
189
190
# File 'lib/inspec/profile_context.rb', line 185

def unregister_rule(id)
  @rules.delete(full_id(@profile_id, id))
  @control_subcontexts.each do |c|
    c.unregister_rule(id)
  end
end