cfn-nag 0.3.10 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3c3a861a811bf0119e1a57ace0afd754bbdcb70a
4
- data.tar.gz: fa4e2b55a38e1992ebe5473287c1c7342f97a168
3
+ metadata.gz: d28e143a404043d2d72720c13b3185b7fb150846
4
+ data.tar.gz: 054364ac8afe5ae75fd4d4afdc1920d42fcc8c58
5
5
  SHA512:
6
- metadata.gz: a33c84416c3759da2d6f7f1c246f58227d71d5e7141f8fada3a148e3f1c37b3efa1edeebe64cbb33830eda0ef85209f27a25c980b80a93b939b2f38b357b5705
7
- data.tar.gz: b8e534a94801cd6f1b6945bb3495a743fd85cad56da730390307fb4fb37d1fb86c1096e500ae3884a885813dcbbe6159900731f519e67f7b4254ad496f1623e2
6
+ metadata.gz: 55346cb4a2298a66d24ed27b5bb151be4a598586e09d925ac998223c6d1a8d4e4886751d02eb8327a93244f454a00ac611c0c8ef9929885258a21677278a405d
7
+ data.tar.gz: b5b11a2eafdc8d814a3fcbdaad095fbf985980571d67b8b2c9ce861af7efd6edd898030841c8e115aaaa14cfc3d97f8bae980acb63e204ecd94fa06d1db5babe
@@ -8,6 +8,8 @@ opts = Trollop::options do
8
8
  usage '[options] <cloudformation template path ...>|<cloudformation template in STDIN>'
9
9
 
10
10
  opt :debug, 'Enable debug output', type: :boolean, required: false, default: false
11
+ opt :allow_suppression, 'Allow using Metadata to suppress violations', type: :boolean, required: false, default: true
12
+ opt :print_suppression, 'Emit suppressions to stderr', type: :boolean, required: false, default: false
11
13
  opt :rule_directory, 'Extra rule directory', type: :io, required: false, default: nil
12
14
  opt :profile_path, 'Path to a profile file', type: :io, required: false, default: nil
13
15
  end
@@ -20,7 +22,9 @@ unless opts[:profile_path].nil?
20
22
  end
21
23
 
22
24
  cfn_nag = CfnNag.new(profile_definition: profile_definition,
23
- rule_directory: opts[:rule_directory])
25
+ rule_directory: opts[:rule_directory],
26
+ allow_suppression: opts[:allow_suppression],
27
+ print_suppression: opts[:print_suppression])
24
28
 
25
29
  # trollop appears to pop args off of ARGV
26
30
  # ARGF concatenates which we don't want
@@ -10,6 +10,8 @@ opts = Trollop::options do
10
10
  opt :debug, 'Enable debug output', type: :boolean, required: false, default: false
11
11
  opt :rule_directory, 'Extra rule directory', type: :io, required: false, default: nil
12
12
  opt :profile_path, 'Path to a profile file', type: :io, required: false, default: nil
13
+ opt :allow_suppression, 'Allow using Metadata to suppress violations', type: :boolean, required: false, default: true
14
+ opt :print_suppression, 'Emit suppressions to stderr', type: :boolean, required: false, default: false
13
15
  end
14
16
 
15
17
  Trollop::die(:output_format,
@@ -23,7 +25,9 @@ unless opts[:profile_path].nil?
23
25
  end
24
26
 
25
27
  cfn_nag = CfnNag.new(profile_definition: profile_definition,
26
- rule_directory: opts[:rule_directory])
28
+ rule_directory: opts[:rule_directory],
29
+ allow_suppression: opts[:allow_suppression],
30
+ print_suppression: opts[:print_suppression])
27
31
 
28
32
  exit cfn_nag.audit_aggregate_across_files_and_render_results(input_path: opts[:input_path],
29
33
  output_format: opts[:output_format])
@@ -9,9 +9,13 @@ require 'logging'
9
9
 
10
10
  class CfnNag
11
11
  def initialize(profile_definition: nil,
12
- rule_directory: nil)
12
+ rule_directory: nil,
13
+ allow_suppression: true,
14
+ print_suppression: false)
13
15
  @rule_directory = rule_directory
14
- @custom_rule_loader = CustomRuleLoader.new(rule_directory: rule_directory)
16
+ @custom_rule_loader = CustomRuleLoader.new(rule_directory: rule_directory,
17
+ allow_suppression: allow_suppression,
18
+ print_suppression: print_suppression)
15
19
  @profile_definition = profile_definition
16
20
  end
17
21
 
@@ -9,8 +9,12 @@ require 'cfn-nag/jmes_path_discovery'
9
9
  # apply these rules to a CfnModel object
10
10
  #
11
11
  class CustomRuleLoader
12
- def initialize(rule_directory: nil)
12
+ def initialize(rule_directory: nil,
13
+ allow_suppression: true,
14
+ print_suppression: false)
13
15
  @rule_directory = rule_directory
16
+ @allow_suppression = allow_suppression
17
+ @print_suppression = print_suppression
14
18
  validate_extra_rule_directory rule_directory
15
19
  end
16
20
 
@@ -34,13 +38,19 @@ class CustomRuleLoader
34
38
  rule_registry
35
39
  end
36
40
 
41
+
37
42
  def execute_custom_rules(cfn_model)
38
43
  Logging.logger['log'].debug "cfn_model: #{cfn_model}"
39
44
 
40
45
  violations = []
41
46
 
47
+ validate_cfn_nag_metadata(cfn_model)
48
+
42
49
  discover_rule_classes(@rule_directory).each do |rule_class|
43
- audit_result = rule_class.new.audit(cfn_model)
50
+ filtered_cfn_model = cfn_model_with_suppressed_resources_removed cfn_model: cfn_model,
51
+ rule_id: rule_class.new.rule_id,
52
+ allow_suppression: @allow_suppression
53
+ audit_result = rule_class.new.audit(filtered_cfn_model)
44
54
  violations << audit_result unless audit_result.nil?
45
55
  end
46
56
 
@@ -56,6 +66,66 @@ class CustomRuleLoader
56
66
 
57
67
  private
58
68
 
69
+ def rules_to_suppress(resource)
70
+ if resource.metadata && resource.metadata['cfn_nag'] && resource.metadata['cfn_nag']['rules_to_suppress']
71
+ resource.metadata['cfn_nag']['rules_to_suppress']
72
+ else
73
+ nil
74
+ end
75
+ end
76
+
77
+ def validate_cfn_nag_metadata(cfn_model)
78
+ mangled_metadatas = []
79
+ cfn_model.resources.each do |logical_resource_id, resource|
80
+ resource_rules_to_suppress = rules_to_suppress resource
81
+ if resource_rules_to_suppress.nil?
82
+ next
83
+ else
84
+ mangled_rules = resource_rules_to_suppress.select do |rule_to_suppress|
85
+ rule_to_suppress['id'].nil?
86
+ end
87
+ unless mangled_rules.empty?
88
+ mangled_metadatas << [logical_resource_id, mangled_rules]
89
+ end
90
+ end
91
+ end
92
+ mangled_metadatas.each do |mangled_metadata|
93
+ logical_resource_id = mangled_metadata.first
94
+ mangled_rules = mangled_metadata[1]
95
+
96
+ STDERR.puts "#{logical_resource_id} has missing cfn_nag suppression rule id: #{mangled_rules}"
97
+ end
98
+ end
99
+
100
+ def suppress_resource?(rules_to_suppress, rule_id, logical_resource_id)
101
+ found_suppression_rule = rules_to_suppress.find do |rule_to_suppress|
102
+ next if rule_to_suppress['id'].nil?
103
+ rule_to_suppress['id'] == rule_id
104
+ end
105
+ if found_suppression_rule && @print_suppression
106
+ STDERR.puts "Suppressing #{rule_id} on #{logical_resource_id} for reason: #{found_suppression_rule['reason']}"
107
+ end
108
+ !found_suppression_rule.nil?
109
+ end
110
+
111
+ def cfn_model_with_suppressed_resources_removed(cfn_model:,
112
+ rule_id:,
113
+ allow_suppression:)
114
+ return cfn_model unless allow_suppression
115
+
116
+ cfn_model = cfn_model.copy
117
+
118
+ cfn_model.resources.delete_if do |logical_resource_id, resource|
119
+ rules_to_suppress = rules_to_suppress resource
120
+ if rules_to_suppress.nil?
121
+ false
122
+ else
123
+ suppress_resource?(rules_to_suppress, rule_id, logical_resource_id)
124
+ end
125
+ end
126
+ cfn_model
127
+ end
128
+
59
129
  def validate_extra_rule_directory(rule_directory)
60
130
  unless rule_directory.nil?
61
131
  fail "Not a real directory #{rule_directory}" unless File.directory? rule_directory
@@ -1,6 +1,9 @@
1
1
  require 'jmespath'
2
2
  require 'logging'
3
3
 
4
+ ##
5
+ # THIS DOES NOT RESPECT SUPPRESSIONS!!!!!!
6
+ ##
4
7
  class JmesPathEvaluator
5
8
  def initialize(cfn_model)
6
9
  @cfn_model = cfn_model
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfn-nag
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.10
4
+ version: 0.3.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Kascic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-15 00:00:00.000000000 Z
11
+ date: 2017-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logging
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: 0.1.9
47
+ version: 0.1.11
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: 0.1.9
54
+ version: 0.1.11
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: jmespath
57
57
  requirement: !ruby/object:Gem::Requirement