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_jsonObject

Returns the value of attribute input_json.



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

def input_json
  @input_json
end

Class Method Details

.count_failures(violations) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/rule.rb', line 107

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



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rule.rb', line 94

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)


90
91
92
# File 'lib/rule.rb', line 90

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

Instance Method Details

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

this is to record a violation as opposed to “registering” a violation

not super keen on this looking at it after the fact.… @violations will have to live in the object this Rule is mixed into i.e. CfnNag



124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/rule.rb', line 124

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

#assertion(id:, jq:, message:) ⇒ Object



83
84
85
86
87
88
# File 'lib/rule.rb', line 83

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

#fatal_assertion(id:, jq:, message:) ⇒ Object



51
52
53
54
55
56
57
# File 'lib/rule.rb', line 51

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

#fatal_violation(id:, jq:, message:) ⇒ Object



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

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

#raw_fatal_assertion(id:, jq:, message:) ⇒ Object



42
43
44
45
46
47
48
49
# File 'lib/rule.rb', line 42

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

#raw_fatal_violation(id:, jq:, message:) ⇒ Object



59
60
61
62
63
64
65
66
# File 'lib/rule.rb', line 59

def raw_fatal_violation(id:, jq:, message:)
  failing_rule(id: id,
               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(id:, jq:, message:) ⇒ Object



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

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

#warning(id:, jq:, message:) ⇒ Object



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

def warning(id:, jq:, message:)
  warning_def = @rule_registry.definition(id: id,
                                          type: Violation::WARNING,
                                          message: message)

  return if @stop_processing

  Logging.logger['log'].debug jq

  stdout = jq_command(@input_json, 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(id: warning_def.id,
                  type: Violation::WARNING,
                  message: message,
                  logical_resource_ids: resource_ids)
  end
end