Module: Bootprint::Rules

Defined in:
lib/bootprint/rules.rb,
lib/bootprint/rules/rule.rb,
lib/bootprint/rules/builtin.rb,
lib/bootprint/rules/finding.rb,
lib/bootprint/rules/registry.rb

Defined Under Namespace

Modules: Builtin, Registry Classes: Finding, Rule

Constant Summary collapse

SEVERITY_ORDER =
{ info: 0, warning: 1, error: 2, critical: 3 }.freeze

Class Method Summary collapse

Class Method Details

.define(id, severity: nil, &block) ⇒ Object



11
12
13
14
15
# File 'lib/bootprint/rules.rb', line 11

def define(id, severity: nil, &block)
  rule = Rule.new(id, severity:)
  rule.instance_eval(&block)
  Registry.add(rule)
end

.evaluate(source, target, policy: Policy.new, only: nil, minimum_severity: nil) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/bootprint/rules.rb', line 25

def evaluate(source, target, policy: Policy.new, only: nil, minimum_severity: nil)
  categories = Array(only).map(&:to_sym)
  minimum = (minimum_severity || policy.minimum_severity).to_sym
  Registry.all.filter_map do |rule|
    next if !categories.empty? && !categories.include?(rule.category)

    finding = begin
      rule.evaluate(source, target, policy:)
    rescue StandardError => error
      Finding.new(
        rule_id: "#{rule.id}-evaluation-failure",
        title: "Diagnostic rule failed",
        category: :internal,
        severity: policy.plugin_strict? ? :error : :warning,
        summary: "Rule #{rule.id} could not evaluate this snapshot.",
        cause: Sanitizer.text("#{error.class}: #{error.message}"),
        impact: "This rule's diagnosis is incomplete; other rules continued.",
        evidence: { "rule_id" => rule.id },
        remediation: { "summary" => "Update the rule provider or Bootprint.", "commands" => [], "files" => [] },
        references: [], metadata: {}, suppressed: false
      )
    end
    next unless finding
    next if SEVERITY_ORDER.fetch(finding.severity) < SEVERITY_ORDER.fetch(minimum)

    finding
  end
end

.register(name_or_rule) ⇒ Object



17
18
19
20
21
22
23
# File 'lib/bootprint/rules.rb', line 17

def register(name_or_rule)
  return Registry.add(name_or_rule) if name_or_rule.is_a?(Rule)

  require "bootprint/rules/#{name_or_rule}"
rescue LoadError => error
  raise ConfigurationError, "Could not load Bootprint rules for #{name_or_rule}: #{error.message}"
end