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 +4 -4
- data/bin/cfn_nag +5 -1
- data/bin/cfn_nag_scan +5 -1
- data/lib/cfn-nag/cfn_nag.rb +6 -2
- data/lib/cfn-nag/custom_rule_loader.rb +72 -2
- data/lib/cfn-nag/jmes_path_evaluator.rb +3 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d28e143a404043d2d72720c13b3185b7fb150846
|
4
|
+
data.tar.gz: 054364ac8afe5ae75fd4d4afdc1920d42fcc8c58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55346cb4a2298a66d24ed27b5bb151be4a598586e09d925ac998223c6d1a8d4e4886751d02eb8327a93244f454a00ac611c0c8ef9929885258a21677278a405d
|
7
|
+
data.tar.gz: b5b11a2eafdc8d814a3fcbdaad095fbf985980571d67b8b2c9ce861af7efd6edd898030841c8e115aaaa14cfc3d97f8bae980acb63e204ecd94fa06d1db5babe
|
data/bin/cfn_nag
CHANGED
@@ -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
|
data/bin/cfn_nag_scan
CHANGED
@@ -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])
|
data/lib/cfn-nag/cfn_nag.rb
CHANGED
@@ -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
|
-
|
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
|
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.
|
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-
|
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.
|
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.
|
54
|
+
version: 0.1.11
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: jmespath
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|