Module: Inspec::Utils::RunDataFilters

Included in:
Plugin::V2::PluginType::Reporter, Reporters::Base
Defined in:
lib/inspec/utils/run_data_filters.rb

Overview

RunDataFilters is a mixin for core Reporters and plugin reporters. The methods operate on the run_data Hash (prior to any conversion to a full RunData object).

All methods here operate using the run_data accessor and modify

its contents in place (if needed).

Instance Method Summary collapse

Instance Method Details

#apply_report_resize_optionsObject

Apply options such as message and code_desc truncation, and removal of backtraces



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/inspec/utils/run_data_filters.rb', line 23

def apply_report_resize_options
  runtime_config = @config[:runtime_config]

  message_truncation = runtime_config[:reporter_message_truncation] || "ALL"
  @trunc = message_truncation == "ALL" ? -1 : message_truncation.to_i
  include_backtrace = runtime_config[:reporter_backtrace_inclusion].nil? ? true : runtime_config[:reporter_backtrace_inclusion]

  @run_data[:profiles]&.each do |p|
    p[:controls].each do |c|
      c[:results]&.map! do |r|
        r.delete(:backtrace) unless include_backtrace
        process_truncation(r)
      end
    end
  end
end

#apply_run_data_filters_to_hashObject

Long name, but we want to be clear this operates on the Hash This is the only method that client libraries need to call; any future feature growth should be handled internally here.



13
14
15
16
17
18
19
20
# File 'lib/inspec/utils/run_data_filters.rb', line 13

def apply_run_data_filters_to_hash
  @config[:runtime_config] = Inspec::Config.cached || {}
  apply_report_resize_options
  filter_empty_profiles
  redact_sensitive_inputs
  suppress_diff_output
  sort_controls
end

#filter_empty_profilesObject

Filters profiles from report which don’t have controls in it.



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

def filter_empty_profiles
  runtime_config = @config[:runtime_config]
  if runtime_config[:filter_empty_profiles] && @run_data[:profiles].count > 1
    @run_data[:profiles].delete_if { |p| p[:controls].empty? }
  end
end

#redact_sensitive_inputsObject

Find any inputs with :sensitive = true and replace their values with “***”



49
50
51
52
53
54
55
56
57
# File 'lib/inspec/utils/run_data_filters.rb', line 49

def redact_sensitive_inputs
  @run_data[:profiles]&.each do |p|
    p[:inputs]&.each do |i|
      next unless i[:options][:sensitive]

      i[:options][:value] = "***"
    end
  end
end

#sort_controlsObject

Optionally sort controls within each profile in report



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/inspec/utils/run_data_filters.rb', line 78

def sort_controls
  sort_type = @config[:runtime_config][:sort_results_by]
  return unless sort_type
  return if sort_type == "none"

  @run_data[:profiles]&.each do |p|
    p[:controls] ||= []
    p[:groups] ||= []

    case sort_type
    when "control"
      p[:controls].sort_by! { |c| c[:id] }
    when "random"
      p[:controls].shuffle!
    when "file"
      # Sort the controls by file, but preserve order within the file.
      # Files are called "groups" in the run_data, and the filename is in the id.
      sorted_control_ids = p[:groups].sort_by { |g| g[:id] }.map { |g| g[:controls] }.flatten
      controls_by_id = {}
      p[:controls].each { |c| controls_by_id[c[:id]] = c }
      p[:controls] = sorted_control_ids.map { |cid| controls_by_id[cid] }
    end
  end
end

#suppress_diff_outputObject

Optionally suppress diff output in the message field



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/inspec/utils/run_data_filters.rb', line 60

def suppress_diff_output
  return if @config[:runtime_config][:diff]

  @run_data[:profiles]&.each do |p|
    p[:controls]&.each do |c|
      c[:results]&.each do |r|
        next unless r[:message] # :message only set on failure

        pos = r[:message].index(/\n{1,2}Diff.*:/)
        next unless pos # Only textual tests get Diffs

        r[:message] = r[:message].slice(0, pos)
      end
    end
  end
end