Module: Rule

Included in:
CfnNag
Defined in:
lib/rule.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#input_json_pathObject

Returns the value of attribute input_json_path.



5
6
7
# File 'lib/rule.rb', line 5

def input_json_path
  @input_json_path
end

Class Method Details

.count_failures(violations) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/rule.rb', line 98

def self.count_failures(violations)
  violations.inject(0) do |count, violation|
    if violation.type == Violation::FAILING_VIOLATION
      if empty?(violation.logical_resource_ids)
        count += 1
      else
        count += violation.logical_resource_ids.size
      end
    end
    count
  end
end

.count_warnings(violations) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rule.rb', line 85

def self.count_warnings(violations)
  violations.inject(0) do |count, violation|
    if violation.type == Violation::WARNING
      if empty?(violation.logical_resource_ids)
        count += 1
      else
        count += violation.logical_resource_ids.size
      end
    end
    count
  end
end

.empty?(array) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/rule.rb', line 81

def self.empty?(array)
  array.nil? or array.size ==0
end

Instance Method Details

#add_violation(type:, message:, logical_resource_ids: nil, violating_code: nil) ⇒ Object



111
112
113
114
115
116
117
118
119
120
# File 'lib/rule.rb', line 111

def add_violation(type:,
                  message:,
                  logical_resource_ids: nil,
                  violating_code: nil)
  violation = Violation.new(type: type,
                            message: message,
                            logical_resource_ids: logical_resource_ids,
                            violating_code: violating_code)
  @violations << violation
end

#assertion(jq:, message:) ⇒ Object



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

def assertion(jq:, message:)
  failing_rule(jq_expression: jq,
               fail_if_found: false,
               message: message)
end

#fatal_assertion(jq:, message:) ⇒ Object



47
48
49
50
51
52
# File 'lib/rule.rb', line 47

def fatal_assertion(jq:, message:)
  failing_rule(jq_expression: jq,
               fail_if_found: false,
               fatal: true,
               message: message)
end

#fatal_violation(jq:, message:) ⇒ Object



62
63
64
65
66
67
# File 'lib/rule.rb', line 62

def fatal_violation(jq:, message:)
  failing_rule(jq_expression: jq,
               fail_if_found: true,
               fatal: true,
               message: message)
end

#raw_fatal_assertion(jq:, message:) ⇒ Object



39
40
41
42
43
44
45
# File 'lib/rule.rb', line 39

def raw_fatal_assertion(jq:, message:)
  failing_rule(jq_expression: jq,
               fail_if_found: false,
               fatal: true,
               message: message,
               raw: true)
end

#raw_fatal_violation(jq:, message:) ⇒ Object



54
55
56
57
58
59
60
# File 'lib/rule.rb', line 54

def raw_fatal_violation(jq:, message:)
  failing_rule(jq_expression: jq,
               fail_if_found: true,
               fatal: true,
               message: message,
               raw: true)
end

#resourcesObject

jq preamble to spit out Resources but as an array of key-value pairs can be used in jq rule definition but… this is probably reducing replication at the cost of opaqueness



9
10
11
# File 'lib/rule.rb', line 9

def resources
  '.Resources|with_entries(.value.LogicalResourceId = .key)[]'
end

#resources_by_type(resource) ⇒ Object

jq to filter Cloudformation resources by Type can be used in jq rule definition but… this is probably reducing replication at the cost of opaqueness



15
16
17
# File 'lib/rule.rb', line 15

def resources_by_type(resource)
  "#{resources}| select(.Type == \"#{resource}\")"
end

#violation(jq:, message:) ⇒ Object



69
70
71
72
73
# File 'lib/rule.rb', line 69

def violation(jq:, message:)
  failing_rule(jq_expression: jq,
               fail_if_found: true,
               message: message)
end

#warning(jq:, message:) ⇒ Object



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

def warning(jq:, message:)
  @warning_registry << message

  return if @stop_processing

  Logging.logger['log'].debug jq

  stdout = jq_command(@input_json_path, jq)
  result = $?.exitstatus
  scrape_jq_output_for_error(jq, stdout)

  resource_ids = parse_logical_resource_ids(stdout)
  new_warnings = resource_ids.size
  if result == 0 and new_warnings > 0
    add_violation(type: Violation::WARNING,
                  message: message,
                  logical_resource_ids: resource_ids)
  end
end