inspec_tools 0.0.0.1.ENOTAG

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +662 -0
  3. data/LICENSE.md +15 -0
  4. data/README.md +329 -0
  5. data/Rakefile +30 -0
  6. data/exe/inspec_tools +14 -0
  7. data/lib/data/NIST_Map_02052020_CIS_Controls_Version_7.1_Implementation_Groups_1.2.xlsx +0 -0
  8. data/lib/data/NIST_Map_09212017B_CSC-CIS_Critical_Security_Controls_VER_6.1_Excel_9.1.2016.xlsx +0 -0
  9. data/lib/data/README.TXT +25 -0
  10. data/lib/data/U_CCI_List.xml +38403 -0
  11. data/lib/data/attributes.yml +23 -0
  12. data/lib/data/cci2html.xsl +136 -0
  13. data/lib/data/mapping.yml +17 -0
  14. data/lib/data/stig.csv +1 -0
  15. data/lib/data/threshold.yaml +83 -0
  16. data/lib/exceptions/impact_input_error.rb +6 -0
  17. data/lib/exceptions/severity_input_error.rb +6 -0
  18. data/lib/happy_mapper_tools/benchmark.rb +161 -0
  19. data/lib/happy_mapper_tools/cci_attributes.rb +66 -0
  20. data/lib/happy_mapper_tools/stig_attributes.rb +196 -0
  21. data/lib/happy_mapper_tools/stig_checklist.rb +99 -0
  22. data/lib/inspec_tools.rb +17 -0
  23. data/lib/inspec_tools/ckl.rb +20 -0
  24. data/lib/inspec_tools/cli.rb +31 -0
  25. data/lib/inspec_tools/csv.rb +101 -0
  26. data/lib/inspec_tools/help.rb +9 -0
  27. data/lib/inspec_tools/help/compliance.md +7 -0
  28. data/lib/inspec_tools/help/csv2inspec.md +5 -0
  29. data/lib/inspec_tools/help/inspec2ckl.md +5 -0
  30. data/lib/inspec_tools/help/inspec2csv.md +5 -0
  31. data/lib/inspec_tools/help/inspec2xccdf.md +5 -0
  32. data/lib/inspec_tools/help/pdf2inspec.md +6 -0
  33. data/lib/inspec_tools/help/summary.md +5 -0
  34. data/lib/inspec_tools/help/xccdf2inspec.md +5 -0
  35. data/lib/inspec_tools/inspec.rb +331 -0
  36. data/lib/inspec_tools/pdf.rb +136 -0
  37. data/lib/inspec_tools/plugin.rb +15 -0
  38. data/lib/inspec_tools/plugin_cli.rb +278 -0
  39. data/lib/inspec_tools/summary.rb +126 -0
  40. data/lib/inspec_tools/version.rb +8 -0
  41. data/lib/inspec_tools/xccdf.rb +155 -0
  42. data/lib/inspec_tools/xlsx_tool.rb +148 -0
  43. data/lib/inspec_tools_plugin.rb +7 -0
  44. data/lib/overrides/false_class.rb +5 -0
  45. data/lib/overrides/nil_class.rb +5 -0
  46. data/lib/overrides/object.rb +5 -0
  47. data/lib/overrides/string.rb +5 -0
  48. data/lib/overrides/true_class.rb +5 -0
  49. data/lib/utilities/csv_util.rb +14 -0
  50. data/lib/utilities/extract_nist_cis_mapping.rb +57 -0
  51. data/lib/utilities/extract_pdf_text.rb +20 -0
  52. data/lib/utilities/inspec_util.rb +435 -0
  53. data/lib/utilities/parser.rb +373 -0
  54. data/lib/utilities/text_cleaner.rb +69 -0
  55. metadata +359 -0
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+
3
+ require 'happymapper'
4
+ require 'nokogiri'
5
+
6
+ # rubocop:disable Naming/ClassAndModuleCamelCase
7
+
8
+ module HappyMapperTools
9
+ module CCIAttributes
10
+ class Reference
11
+ include HappyMapper
12
+ tag 'reference'
13
+
14
+ attribute :creator, String, tag: 'creator'
15
+ attribute :title, String, tag: 'title'
16
+ attribute :version, String, tag: 'version'
17
+ attribute :location, String, tag: 'location'
18
+ attribute :index, String, tag: 'index'
19
+ end
20
+
21
+ class CCI_Item
22
+ include HappyMapper
23
+ tag 'cci_item'
24
+
25
+ attribute :id, String, tag: 'id'
26
+ element :status, String, tag: 'status'
27
+ element :publishdate, String, tag: 'publishdate'
28
+ element :contributor, String, tag: 'contributor'
29
+ element :definition, String, tag: 'definition'
30
+ element :type, String, tag: 'type'
31
+ has_many :references, Reference, xpath: 'xmlns:references'
32
+ end
33
+
34
+ class Metadata
35
+ include HappyMapper
36
+ tag 'metadata'
37
+
38
+ element :version, String, tag: 'version'
39
+ element :publishdate, String, tag: 'publishdate'
40
+ end
41
+
42
+ class CCI_List
43
+ include HappyMapper
44
+ tag 'cci_list'
45
+
46
+ attribute :xsi, String, tag: 'xsi', namespace: 'xmlns'
47
+ attribute :schemaLocation, String, tag: 'schemaLocation', namespace: 'xmlns'
48
+ has_one :metadata, Metadata, tag: 'metadata'
49
+ has_many :cci_items, CCI_Item, xpath: 'xmlns:cci_items'
50
+
51
+ def fetch_nists(ccis)
52
+ ccis = [ccis] unless ccis.is_a?(Array)
53
+
54
+ # some of the XCCDF files were having CCE- tags show up which
55
+ # we don't support, not sure if this is a typo on their part or
56
+ # we need to see about supporting CCE tags but ... for now
57
+ filtered_ccis = ccis.select { |f| /CCI-/.match(f) }
58
+ filtered_ccis.map do |cci|
59
+ cci_items.find { |item| item.id == cci }.references.max_by(&:version).index
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ # rubocop:enable Naming/ClassAndModuleCamelCase
@@ -0,0 +1,196 @@
1
+ # encoding: utf-8
2
+
3
+ module HappyMapperTools
4
+ module StigAttributes
5
+ require 'happymapper'
6
+ require 'nokogiri'
7
+ require 'colorize'
8
+
9
+ class ContentRef
10
+ include HappyMapper
11
+ tag 'check-content-ref'
12
+ attribute :name, String, tag: 'name'
13
+ attribute :href, String, tag: 'href'
14
+ end
15
+
16
+ class Check
17
+ include HappyMapper
18
+ tag 'check'
19
+
20
+ element :content_ref, ContentRef, tag: 'check-content-ref'
21
+ element :content, String, tag: 'check-content'
22
+ end
23
+
24
+ class Fix
25
+ include HappyMapper
26
+ tag 'fix'
27
+
28
+ attribute :id, String, tag: 'id'
29
+ end
30
+
31
+ class DescriptionDetails
32
+ include HappyMapper
33
+ tag 'Details'
34
+
35
+ element :vuln_discussion, String, tag: 'VulnDiscussion'
36
+ element :false_positives, String, tag: 'FalsePositives'
37
+ element :false_negatives, String, tag: 'FalseNegatives'
38
+ element :documentable, Boolean, tag: 'Documentable'
39
+ element :mitigations, String, tag: 'Mitigations'
40
+ element :severity_override_guidance, String, tag: 'SeverityOverrideGuidance'
41
+ element :potential_impacts, String, tag: 'PotentialImpacts'
42
+ element :third_party_tools, String, tag: 'ThirdPartyTools'
43
+ element :mitigation_controls, String, tag: 'MitigationControl'
44
+ element :responsibility, String, tag: 'Responsibility'
45
+ element :ia_controls, String, tag: 'IAControls'
46
+ end
47
+
48
+ class Description
49
+ include HappyMapper
50
+ tag 'description'
51
+
52
+ content :details, DescriptionDetails
53
+
54
+ detail_tags = %i(vuln_discussion false_positives false_negatives documentable
55
+ mitigations severity_override_guidance potential_impacts
56
+ third_party_tools mitigation_controls responsibility ia_controls)
57
+
58
+ detail_tags.each do |name|
59
+ define_method name do
60
+ details.send(name)
61
+ end
62
+ end
63
+ end
64
+
65
+ class ReferenceInfo
66
+ include HappyMapper
67
+ tag 'reference'
68
+
69
+ attribute :href, String, tag: 'href'
70
+ element :dc_publisher, String, tag: 'publisher', namespace: 'dc'
71
+ element :dc_source, String, tag: 'source', namespace: 'dc'
72
+ element :dc_title, String, tag: 'title', namespace: 'dc'
73
+ element :dc_type, String, tag: 'type', namespace: 'dc'
74
+ element :dc_subject, String, tag: 'subject', namespace: 'dc'
75
+ element :dc_identifier, String, tag: 'identifier', namespace: 'dc'
76
+ end
77
+
78
+ class Rule
79
+ include HappyMapper
80
+ tag 'Rule'
81
+
82
+ attribute :id, String, tag: 'id'
83
+ attribute :severity, String, tag: 'severity'
84
+ element :version, String, tag: 'version'
85
+ element :title, String, tag: 'title'
86
+ has_one :description, Description, tag: 'description'
87
+ element :reference, ReferenceInfo, tag: 'reference'
88
+ has_many :idents, String, tag: 'ident'
89
+ element :fixtext, String, tag: 'fixtext'
90
+ has_one :fix, Fix, tag: 'fix'
91
+ has_one :check, Check, tag: 'check'
92
+ end
93
+
94
+ class Group
95
+ include HappyMapper
96
+ tag 'Group'
97
+
98
+ attribute :id, String, tag: 'id'
99
+ element :title, String, tag: 'title'
100
+ element :description, String, tag: 'description'
101
+ has_one :rule, Rule, tag: 'Rule'
102
+ end
103
+
104
+ class ReleaseDate
105
+ include HappyMapper
106
+ tag 'status'
107
+
108
+ attribute :release_date, String, tag: 'date'
109
+ end
110
+
111
+ class Notice
112
+ include HappyMapper
113
+ tag 'notice'
114
+ attribute :id, String, tag: 'id'
115
+ attribute :xml_lang, String, namespace: 'xml', tag: 'lang'
116
+ content :notice, String, tag: 'notice'
117
+ end
118
+
119
+ class Plaintext
120
+ include HappyMapper
121
+ tag 'plain-text'
122
+ attribute :id, String, tag: 'id'
123
+ content :plaintext, String
124
+ end
125
+
126
+ class Benchmark
127
+ include HappyMapper
128
+ tag 'Benchmark'
129
+
130
+ has_one :release_date, ReleaseDate, tag: 'status'
131
+ attribute :id, String, tag: 'id'
132
+ element :status, String, tag: 'status'
133
+ element :title, String, tag: 'title'
134
+ element :description, String, tag: 'description'
135
+ element :version, String, tag: 'version'
136
+ element :notice, Notice, tag: 'notice'
137
+ has_one :reference, ReferenceInfo, tag: 'reference'
138
+ element :plaintext, Plaintext, tag: 'plain-text'
139
+ has_many :group, Group, tag: 'Group'
140
+ end
141
+
142
+ class DescriptionDetailsType
143
+ def self.type
144
+ DescriptionDetails
145
+ end
146
+
147
+ def self.apply(value) # rubocop:disable Metrics/AbcSize
148
+ value = value.gsub('&', 'and')
149
+ DescriptionDetails.parse "<Details>#{value}</Details>"
150
+ rescue Nokogiri::XML::SyntaxError
151
+ allowed_tags = %w{VulnDiscussion FalsePositives FalseNegatives Documentable
152
+ Mitigations SeverityOverrideGuidance PotentialImpacts
153
+ PotentialImpacts ThirdPartyTools MitigationControl
154
+ Responsibility IAControls}
155
+
156
+ tags_found = value.scan(%r{(?<=<)([^\/]*?)((?= \/>)|(?=>))}).to_a
157
+
158
+ tags_found = tags_found.uniq.flatten.reject!(&:empty?)
159
+ offending_tags = tags_found - allowed_tags
160
+
161
+ if offending_tags.count > 1
162
+ puts "\n\nThe non-standard tags: #{offending_tags.to_s.colorize(:red)}" \
163
+ ' were found in: ' + "\n\n#{value}"
164
+ else
165
+ puts "\n\nThe non-standard tag: #{offending_tags.to_s.colorize(:red)}" \
166
+ ' was found in: ' + "\n\n#{value}"
167
+ end
168
+ puts "\n\nPlease:\n "
169
+ option_one = '(1) ' + '(best)'.colorize(:green) + ' Use the ' +
170
+ '`-r --replace-tags array` '.colorize(:light_yellow) +
171
+ '(case sensitive) option to replace the offending tags ' \
172
+ 'during processing of the XCCDF ' \
173
+ 'file to use the ' +
174
+ "`$#{offending_tags[0]}` " .colorize(:light_green) +
175
+ 'syntax in your InSpec profile.'
176
+ option_two = '(2) Update your XCCDF file to *not use* non-standard XCCDF ' \
177
+ 'elements within ' +
178
+ '`&lt;`,`&gt;`, `<` '.colorize(:red) +
179
+ 'or '.colorize(:default) +
180
+ '`>` '.colorize(:red) +
181
+ 'as "placeholders", and use something that doesn\'t confuse ' \
182
+ 'the XML parser, such as : ' +
183
+ "`$#{offending_tags[0]}`" .colorize(:light_green)
184
+ puts option_one
185
+ puts "\n"
186
+ puts option_two
187
+ # exit
188
+ end
189
+
190
+ def self.apply?(value, _convert_to_type)
191
+ value.is_a?(String)
192
+ end
193
+ end
194
+ HappyMapper::SupportedTypes.register DescriptionDetailsType
195
+ end
196
+ end
@@ -0,0 +1,99 @@
1
+ # encoding: utf-8
2
+
3
+ require 'happymapper'
4
+ require 'nokogiri'
5
+
6
+ module HappyMapperTools
7
+ module StigChecklist
8
+ # see: https://github.com/dam5s/happymapper
9
+ # Class Asset maps from the 'Asset' from Checklist XML file using HappyMapper
10
+ class Asset
11
+ include HappyMapper
12
+ tag 'ASSET'
13
+ element :role, String, tag: 'ROLE'
14
+ element :type, String, tag: 'ASSET_TYPE'
15
+ element :host_name, String, tag: 'HOST_NAME'
16
+ element :host_ip, String, tag: 'HOST_IP'
17
+ element :host_mac, String, tag: 'HOST_MAC'
18
+ element :host_guid, String, tag: 'HOST_GUID'
19
+ element :host_fqdn, String, tag: 'HOST_FQDN'
20
+ element :tech_area, String, tag: 'TECH_AREA'
21
+ element :target_key, String, tag: 'TARGET_KEY'
22
+ element :web_or_database, String, tag: 'WEB_OR_DATABASE'
23
+ element :web_db_site, String, tag: 'WEB_DB_SITE'
24
+ element :web_db_instance, String, tag: 'WEB_DB_INSTANCE'
25
+ end
26
+
27
+ # Class Asset maps from the 'SI_DATA' from Checklist XML file using HappyMapper
28
+ class SiData
29
+ include HappyMapper
30
+ tag 'SI_DATA'
31
+ element :name, String, tag: 'SID_NAME'
32
+ element :data, String, tag: 'SID_DATA'
33
+ end
34
+
35
+ # Class Asset maps from the 'STIG_INFO' from Checklist XML file using HappyMapper
36
+ class StigInfo
37
+ include HappyMapper
38
+ tag 'STIG_INFO'
39
+ has_many :si_data, SiData, tag: 'SI_DATA'
40
+ end
41
+
42
+ # Class Asset maps from the 'STIG_DATA' from Checklist XML file using HappyMapper
43
+ class StigData
44
+ include HappyMapper
45
+
46
+ def initialize(attrib = nil, data = nil)
47
+ self.attrib = attrib
48
+ self.data = data
49
+ end
50
+
51
+ tag 'STIG_DATA'
52
+ has_one :attrib, String, tag: 'VULN_ATTRIBUTE'
53
+ has_one :data, String, tag: 'ATTRIBUTE_DATA'
54
+ end
55
+
56
+ # Class Asset maps from the 'VULN' from Checklist XML file using HappyMapper
57
+ class Vuln
58
+ include HappyMapper
59
+ tag 'VULN'
60
+ has_many :stig_data, StigData, tag: 'STIG_DATA'
61
+ has_one :status, String, tag: 'STATUS'
62
+ has_one :finding_details, String, tag: 'FINDING_DETAILS'
63
+ has_one :comments, String, tag: 'COMMENTS'
64
+ has_one :severity_override, String, tag: 'SEVERITY_OVERRIDE'
65
+ has_one :severity_justification, String, tag: 'SEVERITY_JUSTIFICATION'
66
+ end
67
+
68
+ # Class Asset maps from the 'iSTIG' from Checklist XML file using HappyMapper
69
+ class IStig
70
+ include HappyMapper
71
+ tag 'iSTIG'
72
+ has_one :stig_info, StigInfo, tag: 'STIG_INFO'
73
+ has_many :vuln, Vuln, tag: 'VULN'
74
+ end
75
+
76
+ # Class Asset maps from the 'STIGS' from Checklist XML file using HappyMapper
77
+ class Stigs
78
+ include HappyMapper
79
+ tag 'STIGS'
80
+ has_one :istig, IStig, tag: 'iSTIG'
81
+ end
82
+
83
+ class Checklist
84
+ include HappyMapper
85
+ tag 'CHECKLIST'
86
+ has_one :asset, Asset, tag: 'ASSET'
87
+ has_one :stig, Stigs, tag: 'STIGS'
88
+
89
+ def where(attrib, data)
90
+ stig.istig.vuln.each do |vuln|
91
+ if vuln.stig_data.any? { |element| element.attrib == attrib && element.data == data }
92
+ # TODO: Handle multiple objects that match the condition
93
+ return vuln
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,17 @@
1
+ $LOAD_PATH.unshift(File.expand_path(__dir__))
2
+ require 'inspec_tools/version'
3
+ require 'rubygems'
4
+
5
+ module InspecTools
6
+ autoload :Help, 'inspec_tools/help'
7
+ autoload :Command, 'inspec_tools/command'
8
+ autoload :CLI, 'inspec_tools/cli'
9
+ autoload :XCCDF, 'inspec_tools/xccdf'
10
+ autoload :PDF, 'inspec_tools/pdf'
11
+ autoload :CSV, 'inspec_tools/csv'
12
+ autoload :CKL, 'inspec_tools/ckl'
13
+ autoload :Inspec, 'inspec_tools/inspec'
14
+ autoload :Summary, 'inspec_tools/summary'
15
+ autoload :Threshold, 'inspec_tools/threshold'
16
+ autoload :XLSXTool, 'inspec_tools/xlsx_tool'
17
+ end
@@ -0,0 +1,20 @@
1
+ module InspecTools
2
+ # Methods for converting from CKL to various formats
3
+ class CKL
4
+ def initialize(ckl)
5
+ @ckl = ckl
6
+ end
7
+
8
+ def to_csv
9
+ # TODO: to_csv
10
+ end
11
+
12
+ def to_xccdf
13
+ # TODO: to_xccdf
14
+ end
15
+
16
+ def to_inspec
17
+ # TODO: to_inspec
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,31 @@
1
+ require 'yaml'
2
+ require 'json'
3
+
4
+ require 'inspec-objects'
5
+ require 'inspec'
6
+ require_relative './plugin_cli.rb'
7
+
8
+ # This tells the ruby cli app to use the same argument parsing as the plugin
9
+ module InspecTools
10
+ CLI = InspecPlugins::InspecToolsPlugin::CliCommand
11
+ end
12
+
13
+ #=====================================================================#
14
+ # Pre-Flight Code
15
+ #=====================================================================#
16
+ help_commands = ['-h', '--help', 'help']
17
+ log_commands = ['-l', '--log-directory']
18
+ version_commands = ['-v', '--version', 'version']
19
+
20
+ #---------------------------------------------------------------------#
21
+ # Adjustments for non-required version commands
22
+ #---------------------------------------------------------------------#
23
+ unless (version_commands & ARGV).empty?
24
+ puts InspecTools::VERSION
25
+ exit 0
26
+ end
27
+
28
+ #---------------------------------------------------------------------#
29
+ # Adjustments for non-required log-directory
30
+ #---------------------------------------------------------------------#
31
+ ARGV.push("--log-directory=#{Dir.pwd}/logs") if (log_commands & ARGV).empty? && (help_commands & ARGV).empty?
@@ -0,0 +1,101 @@
1
+ require 'csv'
2
+ require 'nokogiri'
3
+ require 'word_wrap'
4
+ require 'yaml'
5
+ require 'digest'
6
+
7
+ require_relative '../utilities/inspec_util'
8
+
9
+ # rubocop:disable Metrics/AbcSize
10
+ # rubocop:disable Metrics/PerceivedComplexity
11
+ # rubocop:disable Metrics/CyclomaticComplexity
12
+
13
+ module InspecTools
14
+ # Methods for converting from CSV to various formats
15
+ class CSVTool
16
+ def initialize(csv, mapping, name, verbose = false)
17
+ @name = name
18
+ @csv = csv
19
+ @mapping = mapping
20
+ @verbose = verbose
21
+ @csv.shift if @mapping['skip_csv_header']
22
+ end
23
+
24
+ def to_ckl
25
+ # TODO
26
+ end
27
+
28
+ def to_xccdf
29
+ # TODO
30
+ end
31
+
32
+ def to_inspec
33
+ @controls = []
34
+ @cci_xml = nil
35
+ @profile = {}
36
+ read_cci_xml
37
+ insert_json_metadata
38
+ parse_controls
39
+ @profile['controls'] = @controls
40
+ @profile['sha256'] = Digest::SHA256.hexdigest @profile.to_s
41
+ @profile
42
+ end
43
+
44
+ private
45
+
46
+ def insert_json_metadata
47
+ @profile['name'] = @name
48
+ @profile['title'] = 'InSpec Profile'
49
+ @profile['maintainer'] = 'The Authors'
50
+ @profile['copyright'] = 'The Authors'
51
+ @profile['copyright_email'] = 'you@example.com'
52
+ @profile['license'] = 'Apache-2.0'
53
+ @profile['summary'] = 'An InSpec Compliance Profile'
54
+ @profile['version'] = '0.1.0'
55
+ @profile['supports'] = []
56
+ @profile['attributes'] = []
57
+ @profile['generator'] = {
58
+ 'name': 'inspec_tools',
59
+ 'version': VERSION
60
+ }
61
+ end
62
+
63
+ def read_cci_xml
64
+ cci_list_path = File.join(File.dirname(__FILE__), '../data/U_CCI_List.xml')
65
+ @cci_xml = Nokogiri::XML(File.open(cci_list_path))
66
+ @cci_xml.remove_namespaces!
67
+ rescue StandardError => e
68
+ puts "Exception: #{e.message}"
69
+ end
70
+
71
+ def get_nist_reference(cci_number)
72
+ item_node = @cci_xml.xpath("//cci_list/cci_items/cci_item[@id='#{cci_number}']")[0] unless @cci_xml.nil?
73
+ unless item_node.nil?
74
+ nist_ref = item_node.xpath('./references/reference[not(@version <= preceding-sibling::reference/@version) and not(@version <=following-sibling::reference/@version)]/@index').text
75
+ nist_ver = item_node.xpath('./references/reference[not(@version <= preceding-sibling::reference/@version) and not(@version <=following-sibling::reference/@version)]/@version').text
76
+ end
77
+ [nist_ref, nist_ver]
78
+ end
79
+
80
+ def parse_controls
81
+ @csv.each do |row|
82
+ print '.'
83
+ control = {}
84
+ control['id'] = row[@mapping['control.id']] unless @mapping['control.id'].nil? || row[@mapping['control.id']].nil?
85
+ control['title'] = row[@mapping['control.title']] unless @mapping['control.title'].nil? || row[@mapping['control.title']].nil?
86
+ control['desc'] = row[@mapping['control.desc']] unless @mapping['control.desc'].nil? || row[@mapping['control.desc']].nil?
87
+ control['tags'] = {}
88
+ nist, nist_rev = get_nist_reference(row[@mapping['control.tags']['cci']]) unless @mapping['control.tags']['cci'].nil? || row[@mapping['control.tags']['cci']].nil?
89
+ control['tags']['nist'] = [nist, 'Rev_' + nist_rev] unless nist.nil? || nist_rev.nil?
90
+ @mapping['control.tags'].each do |tag|
91
+ control['tags'][tag.first.to_s] = row[tag.last] unless row[tag.last].nil?
92
+ end
93
+ unless @mapping['control.tags']['severity'].nil? || row[@mapping['control.tags']['severity']].nil?
94
+ control['impact'] = Utils::InspecUtil.get_impact(row[@mapping['control.tags']['severity']])
95
+ control['tags']['severity'] = Utils::InspecUtil.get_impact_string(control['impact'])
96
+ end
97
+ @controls << control
98
+ end
99
+ end
100
+ end
101
+ end