class Inspec::ControlEvalContext
etc).
as the basic DSL of the control files (describe, control, title,
The anonymous class includes the given passed resource_dsl as well
files will be instance_exec’d against.
ControlEvalContext constructs an anonymous class that control
def add_resource(name, new_res)
def add_resource(name, new_res) resources_dsl.module_exec do define_method name.to_sym do |*args| new_res.new(@backend, name.to_s, *args) end end end
def add_resources(context)
def add_resources(context) # # TODO: write real unit tests for this and then make this change: # dsl = context.to_resources_dsl # self.class.include dsl # Inspec::Rule.include dsl self.class.class_eval do include context.to_resources_dsl end # TODO: seriously consider getting rid of the NPM model extend context.to_resources_dsl end
def add_subcontext(context)
def add_subcontext(context) profile_context_owner.add_subcontext(context) end
def attribute(name, options = {})
def attribute(name, options = {}) Inspec.deprecate(:attrs_dsl, "Input name: #{name}, Profile: #{profile_id}") input(name, options) end
def block_location(block, alternate_caller)
def block_location(block, alternate_caller) if block.nil? alternate_caller[/^(.+:\d+):in .+$/, 1] || "unknown" else path, line = block.source_location "#{File.basename(path)}:#{line}" end end
def control(id, opts = {}, &block)
def control(id, opts = {}, &block) opts[:skip_only_if_eval] = @skip_only_if_eval if (controls_list_empty? && tags_list_empty?) || control_exist_in_controls_list?(id) register_control(Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block)) elsif !tags_list_empty? # Inside elsif rule is initialised before registering it because it enables fetching of control tags # This condition is only true when --tags option is used inspec_rule = Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block) tag_ids = control_tags(inspec_rule) register_control(inspec_rule) if tag_exist_in_control_tags?(tag_ids) end end
def control_exist_in_controls_list?(id)
def control_exist_in_controls_list?(id) id_exist_in_list = false if profile_config_exist? id_exist_in_list = @conf["profile"].include_controls_list.any? do |inclusion| # Try to see if the inclusion is a regex, and if it matches inclusion == id || (inclusion.is_a?(Regexp) && inclusion =~ id) end end id_exist_in_list end
def control_tags(inspec_rule)
def control_tags(inspec_rule) all_tags = [] inspec_rule.tag.each do |key, value| all_tags.push(key) all_tags.push(value) unless value.nil? end all_tags.flatten.compact.uniq.map(&:to_s) rescue [] end
def controls_list_empty?
def controls_list_empty? !@conf.empty? && @conf.key?("profile") && @conf["profile"].include_controls_list.empty? || @conf.empty? end
def describe(*args, &block)
the describe block in the context of that control.
generate a control for them automatically and then execute
blocks without declaring an inclosing control. Here, we
Describe allows users to write rspec-like bare describe
def describe(*args, &block) loc = block_location(block, caller(1..1).first) id = "(generated from #{loc} #{SecureRandom.hex})" res = nil rule = Inspec::Rule.new(id, profile_id, resources_dsl, {}) do res = describe(*args, &block) end if controls_list_empty? || control_exist_in_controls_list?(id) register_control(rule, &block) end res end
def initialize(profile_context, resources_dsl, backend, conf, dependencies, require_loader, skip_only_if_eval)
def initialize(profile_context, resources_dsl, backend, conf, dependencies, require_loader, skip_only_if_eval) @profile_context = profile_context @resources_dsl = resources_dsl @backend = backend @conf = conf @dependencies = dependencies @require_loader = require_loader @skip_file_message = nil @skip_file = false @skip_only_if_eval = skip_only_if_eval extend resources_dsl # TODO: remove? push to method_missing? end
def input(input_name, options = {})
def input(input_name, options = {}) if options.empty? # Simply an access, no event here Inspec::InputRegistry.find_or_register_input(input_name, profile_id).value else options[:priority] ||= 20 options[:provider] = :inline_control_code evt = Inspec::Input.infer_event(options) Inspec::InputRegistry.find_or_register_input(input_name, profile_id, event: evt).value end end
def input_object(input_name)
Find the Input object, but don't collapse to a value.
def input_object(input_name) Inspec::InputRegistry.find_or_register_input(input_name, profile_id) end
def only_if(message = nil, &block)
def only_if(message = nil, &block) return unless block return if @skip_file == true return if @skip_only_if_eval == true return if block.yield == true # Apply `set_skip_rule` for other rules in the same file profile_context_owner.rules.values.each do |r| sources_match = r.source_file == block.source_location[0] Inspec::Rule.set_skip_rule(r, true, message) if sources_match end @skip_file_message = message @skip_file = true end
def profile_config_exist?
def profile_config_exist? !@conf.empty? && @conf.key?("profile") && !@conf["profile"].include_controls_list.empty? end
def profile_id
def profile_id profile_context.profile_id end
def profile_name
def profile_name profile_id end
def profile_tag_config_exist?
def profile_tag_config_exist? !@conf.empty? && @conf.key?("profile") && !@conf["profile"].include_tags_list.empty? end
def register_control(control, &block)
def register_control(control, &block) if @skip_file ::Inspec::Rule.set_skip_rule(control, true, @skip_file_message) end unless profile_context_owner.profile_supports_platform? platform = inspec.platform msg = "Profile `#{profile_id}` is not supported on platform #{platform.name}/#{platform.release}." ::Inspec::Rule.set_skip_rule(control, true, msg) end unless profile_context_owner.profile_supports_inspec_version? msg = "Profile `#{profile_id}` is not supported on InSpec version (#{Inspec::VERSION})." ::Inspec::Rule.set_skip_rule(control, true, msg) end profile_context_owner.register_rule(control, &block) unless control.nil? end
def skip_control(id)
def skip_control(id) profile_context_owner.unregister_rule(id) end
def tag_exist_in_control_tags?(tag_ids)
def tag_exist_in_control_tags?(tag_ids) tag_option_matches_with_list = false if !tag_ids.empty? && !tag_ids.nil? && profile_tag_config_exist? tag_option_matches_with_list = !(tag_ids & @conf["profile"].include_tags_list).empty? unless tag_option_matches_with_list @conf["profile"].include_tags_list.any? do |inclusion| # Try to see if the inclusion is a regex, and if it matches if inclusion.is_a?(Regexp) tag_ids.each do |id| tag_option_matches_with_list = (inclusion =~ id) break if tag_option_matches_with_list end end end end end tag_option_matches_with_list end
def tags_list_empty?
def tags_list_empty? !@conf.empty? && @conf.key?("profile") && @conf["profile"].include_tags_list.empty? || @conf.empty? end
def title(arg)
def title(arg) profile_context_owner.set_header(:title, arg) end
def to_s
def to_s "Control Evaluation Context (#{profile_name})" end