Class: CfnNag

Inherits:
Object show all
Includes:
ViolationFiltering
Defined in:
lib/cfn-nag/cfn_nag.rb,
lib/cfn-nag/base_rule.rb

Overview

Base class all Rules should subclass

Defined Under Namespace

Classes: BaseRule

Constant Summary collapse

DEFAULT_TEMPLATE_PATTERN =
'..*\.json$|..*\.yaml$|..*\.yml$|..*\.template$'

Instance Method Summary collapse

Methods included from ViolationFiltering

#filter_violations_by_deny_list, #filter_violations_by_profile

Constructor Details

#initialize(config:) ⇒ CfnNag

Returns a new instance of CfnNag.



20
21
22
# File 'lib/cfn-nag/cfn_nag.rb', line 20

def initialize(config:)
  @config = config
end

Instance Method Details

#audit(cloudformation_string:, parameter_values_string: nil, condition_values_string: nil) ⇒ Object

Given cloudformation json/yml, run all the rules against it

Optionally include JSON with Parameters key to substitute into cfn_model.parameters

Return a hash with failure count



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/cfn-nag/cfn_nag.rb', line 84

def audit(cloudformation_string:, parameter_values_string: nil, condition_values_string: nil)
  violations = []
  begin
    cfn_model = CfnParser.new.parse cloudformation_string,
                                    parameter_values_string,
                                    true,
                                    condition_values_string
    CustomRuleLoader.rule_arguments = @config.rule_arguments
    violations += @config.custom_rule_loader.execute_custom_rules(
      cfn_model,
      @config.custom_rule_loader.rule_definitions
    )

    violations = filter_violations_by_deny_list_and_profile(violations)
    violations = mark_line_numbers_and_element_types(violations, cfn_model)
  rescue RuleRepoException, Psych::SyntaxError, ParserError => fatal_error
    violations << Violation.fatal_violation(fatal_error.to_s)
  rescue JSON::ParserError => json_parameters_error
    error = "JSON Parameter values parse error: #{json_parameters_error}"
    violations << Violation.fatal_violation(error)
  end

  violations = prune_fatal_violations(violations) if @config.ignore_fatal
  audit_result(violations)
end

#audit_aggregate_across_files(input_path:, parameter_values_path: nil, condition_values_path: nil, template_pattern: DEFAULT_TEMPLATE_PATTERN) ⇒ Object

Given a file or directory path, return aggregate results



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/cfn-nag/cfn_nag.rb', line 55

def audit_aggregate_across_files(input_path:,
                                 parameter_values_path: nil,
                                 condition_values_path: nil,
                                 template_pattern: DEFAULT_TEMPLATE_PATTERN)
  parameter_values_string = parameter_values_path.nil? ? nil : File.read(parameter_values_path)
  condition_values_string = condition_values_path.nil? ? nil : File.read(condition_values_path)

  templates = TemplateDiscovery.new.discover_templates(input_json_path: input_path,
                                                       template_pattern: template_pattern)
  aggregate_results = []
  templates.each do |template|
    aggregate_results << {
      filename: template,
      file_results: audit(cloudformation_string: File.read(template),
                          parameter_values_string: parameter_values_string,
                          condition_values_string: condition_values_string)
    }
  end
  aggregate_results
end

#audit_aggregate_across_files_and_render_results(input_path:, output_format: 'txt', parameter_values_path: nil, condition_values_path: nil, template_pattern: DEFAULT_TEMPLATE_PATTERN) ⇒ Object

Given a file or directory path, emit aggregate results to stdout

Return an aggregate failure count (for exit code usage)



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/cfn-nag/cfn_nag.rb', line 29

def audit_aggregate_across_files_and_render_results(input_path:,
                                                    output_format: 'txt',
                                                    parameter_values_path: nil,
                                                    condition_values_path: nil,
                                                    template_pattern: DEFAULT_TEMPLATE_PATTERN)

  aggregate_results = audit_aggregate_across_files input_path: input_path,
                                                   parameter_values_path: parameter_values_path,
                                                   condition_values_path: condition_values_path,
                                                   template_pattern: template_pattern

  render_results(aggregate_results: aggregate_results,
                 output_format: output_format)

  aggregate_results.inject(0) do |total_failure_count, results|
    if @config.fail_on_warnings
      total_failure_count + results[:file_results][:violations].length
    else
      total_failure_count + results[:file_results][:failure_count]
    end
  end
end

#prune_fatal_violations(violations) ⇒ Object



110
111
112
# File 'lib/cfn-nag/cfn_nag.rb', line 110

def prune_fatal_violations(violations)
  violations.reject { |violation| violation.id == 'FATAL' }
end

#render_results(aggregate_results:, output_format:) ⇒ Object



114
115
116
117
# File 'lib/cfn-nag/cfn_nag.rb', line 114

def render_results(aggregate_results:,
                   output_format:)
  results_renderer(output_format).new.render(aggregate_results, @config.custom_rule_loader.rule_definitions)
end