class CfnNag
Base class all Rules should subclass
Top-level CfnNag
class for running profiles
Constants
- DEFAULT_TEMPLATE_PATTERN
Public Class Methods
new(config:)
click to toggle source
# File lib/cfn-nag/cfn_nag.rb, line 19 def initialize(config:) @config = config end
Public Instance Methods
audit(cloudformation_string:, parameter_values_string: nil, condition_values_string: nil)
click to toggle source
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
# File lib/cfn-nag/cfn_nag.rb, line 83 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_blacklist_and_profile(violations) violations = mark_line_numbers(violations, cfn_model) rescue RuleRepoException, Psych::SyntaxError, ParserError => fatal_error violations << fatal_violation(fatal_error.to_s) rescue JSON::ParserError => json_parameters_error error = "JSON Parameter values parse error: #{json_parameters_error}" violations << 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)
click to toggle source
Given a file or directory path, return aggregate results
# File lib/cfn-nag/cfn_nag.rb, line 54 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 : IO.read(parameter_values_path) condition_values_string = condition_values_path.nil? ? nil : IO.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: IO.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)
click to toggle source
Given a file or directory path, emit aggregate results to stdout
Return an aggregate failure count (for exit code usage)
# File lib/cfn-nag/cfn_nag.rb, line 28 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)
click to toggle source
# File lib/cfn-nag/cfn_nag.rb, line 109 def prune_fatal_violations(violations) violations.reject { |violation| violation.id == 'FATAL' } end
render_results(aggregate_results:, output_format:)
click to toggle source
# File lib/cfn-nag/cfn_nag.rb, line 113 def render_results(aggregate_results:, output_format:) results_renderer(output_format).new.render(aggregate_results) end
Private Instance Methods
audit_result(violations)
click to toggle source
# File lib/cfn-nag/cfn_nag.rb, line 148 def audit_result(violations) { failure_count: Violation.count_failures(violations), violations: violations } end
fatal_violation(message)
click to toggle source
# File lib/cfn-nag/cfn_nag.rb, line 155 def fatal_violation(message) Violation.new(id: 'FATAL', type: Violation::FAILING_VIOLATION, message: message) end
filter_violations_by_blacklist_and_profile(violations)
click to toggle source
# File lib/cfn-nag/cfn_nag.rb, line 130 def filter_violations_by_blacklist_and_profile(violations) violations = filter_violations_by_profile( profile_definition: @config.profile_definition, rule_definitions: @config.custom_rule_loader.rule_definitions, violations: violations ) # this must come after - blacklist should always win filter_violations_by_blacklist( blacklist_definition: @config.blacklist_definition, rule_definitions: @config.custom_rule_loader.rule_definitions, violations: violations ) rescue StandardError => blacklist_or_profile_parse_error violations << fatal_violation(blacklist_or_profile_parse_error.to_s) violations end
mark_line_numbers(violations, cfn_model)
click to toggle source
# File lib/cfn-nag/cfn_nag.rb, line 120 def mark_line_numbers(violations, cfn_model) violations.each do |violation| violation.logical_resource_ids.each do |logical_resource_id| violation.line_numbers << cfn_model.line_numbers[logical_resource_id] end end violations end
results_renderer(output_format)
click to toggle source
# File lib/cfn-nag/cfn_nag.rb, line 161 def results_renderer(output_format) registry = { 'colortxt' => ColoredStdoutResults, 'txt' => SimpleStdoutResults, 'json' => JsonResults } registry[output_format] end