cfn-nag 0.3.10 → 0.3.11

Sign up to get free protection for your applications and to get access to all the features.
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