inspec_tools 2.0.6 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +21 -13
- data/Rakefile +82 -8
- data/lib/data/cis_to_nist_critical_controls +0 -0
- data/lib/data/cis_to_nist_mapping +0 -0
- data/lib/happy_mapper_tools/benchmark.rb +83 -0
- data/lib/inspec_tools/csv.rb +42 -39
- data/lib/inspec_tools/generate_map.rb +35 -0
- data/lib/inspec_tools/inspec.rb +19 -91
- data/lib/inspec_tools/pdf.rb +2 -13
- data/lib/inspec_tools/plugin_cli.rb +22 -53
- data/lib/inspec_tools/summary.rb +108 -76
- data/lib/inspec_tools/xlsx_tool.rb +4 -16
- data/lib/utilities/cci_xml.rb +13 -0
- data/lib/utilities/cis_to_nist.rb +11 -0
- data/lib/utilities/inspec_util.rb +11 -76
- data/lib/utilities/mapping_validator.rb +10 -0
- data/lib/utilities/xccdf/from_inspec.rb +89 -0
- data/lib/utilities/xccdf/to_xccdf.rb +388 -0
- data/lib/utilities/xccdf/xccdf_score.rb +116 -0
- metadata +45 -40
- data/CHANGELOG.md +0 -736
- data/lib/data/NIST_Map_02052020_CIS_Controls_Version_7.1_Implementation_Groups_1.2.xlsx +0 -0
- data/lib/data/NIST_Map_09212017B_CSC-CIS_Critical_Security_Controls_VER_6.1_Excel_9.1.2016.xlsx +0 -0
- data/lib/utilities/extract_nist_cis_mapping.rb +0 -57
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f1facda0eab24bdef7fafd9c8c92c5c94efedee3465bbf589b98fd4a61011be2
|
4
|
+
data.tar.gz: a38564b26ff610046007e427c8b45950b743087703224470b0513e94941d6cc7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45b1990c5f4a2e5fa1fd21af344ac9cd9cdf5b60fce134ed80e7e4593a2c315ad09e994d5efc711fa0d6485f26899a5c35dec5e8ba0c37686cfaca9f483304da
|
7
|
+
data.tar.gz: 1022c5eae8dd7e6645e39fae3fbcb4babc195c2876d76d5f6496bb976a7515cb004d476176e19d70bba0507f8c8f1c355f48899c00fb39e79adcc2f26333fc08
|
data/README.md
CHANGED
@@ -70,7 +70,7 @@ Note that all of the above Docker commands will mount your current directory on
|
|
70
70
|
|
71
71
|
### generate_map
|
72
72
|
|
73
|
-
This command will generate a `mapping.
|
73
|
+
This command will generate a `mapping.yml` file that can be passed in to the `csv2inspec` command with the `--m` option.
|
74
74
|
|
75
75
|
```
|
76
76
|
USAGE: inspec_tools generate_map
|
@@ -100,13 +100,15 @@ If the specified threshold is not met, an error code (1) is returned along with
|
|
100
100
|
|
101
101
|
The compliance score are rounded down to the nearest whole number. For example a score of 77.3 would be displayed as 77.
|
102
102
|
|
103
|
+
Thresholds provided inline (i.e. `-i`) override thresholds provided by files (i.e. `-f`).
|
104
|
+
|
103
105
|
```
|
104
106
|
USAGE: inspec_tools compliance [OPTIONS] -j <inspec-json> -i <threshold-inline>
|
105
107
|
inspec_tools compliance [OPTIONS] -j <inspec-json> -f <threshold-file>
|
106
108
|
FLAGS:
|
107
109
|
-j --inspec-json <inspec-json> : path to InSpec results Json
|
108
110
|
-i --template-inline <threshold-inline> : inline compliance threshold definition
|
109
|
-
-f --
|
111
|
+
-f --threshold-file <threshold-file> : yaml file with compliance threshold definition
|
110
112
|
Examples:
|
111
113
|
|
112
114
|
inspec_tools compliance -j examples/sample_json/rhel-simp.json -i '{compliance.min: 80, failed.critical.max: 0, failed.high.max: 0}'
|
@@ -135,11 +137,11 @@ failed.high.max: 1
|
|
135
137
|
|
136
138
|
#### In-Line Examples
|
137
139
|
```
|
138
|
-
{compliance: {min: 90}, failed: {critical: {max: 0}, high: {max: 0}}}
|
140
|
+
"{compliance: {min: 90}, failed: {critical: {max: 0}, high: {max: 0}}}"
|
139
141
|
```
|
140
142
|
|
141
143
|
```
|
142
|
-
{compliance.min: 81, failed.critical.max: 0, failed.high.max: 0}
|
144
|
+
"{compliance.min: 81, failed.critical.max: 0, failed.high.max: 0}"
|
143
145
|
```
|
144
146
|
|
145
147
|
## summary
|
@@ -185,12 +187,16 @@ Using additional flags will override the normal output and only display the outp
|
|
185
187
|
|
186
188
|
USAGE: inspec_tools summary [OPTIONS] -j <inspec-json>
|
187
189
|
|
190
|
+
Thresholds provided inline (i.e. `-i`) override thresholds provided by files (i.e. `-t`).
|
191
|
+
|
192
|
+
|
188
193
|
```
|
189
194
|
FLAGS:
|
190
|
-
-j --inspec-json <inspec-json>
|
191
|
-
-
|
192
|
-
-
|
193
|
-
-
|
195
|
+
-j --inspec-json <inspec-json> : path to InSpec results JSON
|
196
|
+
-f --json-full, --no-json-full : print the summary STDOUT as JSON
|
197
|
+
-k --json-counts, --no-json-counts : print the result status to STDOUT as JSON
|
198
|
+
-t, --threshold-file=THRESHOLD_FILE] : path to threshold YAML file
|
199
|
+
-i, --threshold-inline=THRESHOLD_INLINE] : string of text representing threshold YAML inline
|
194
200
|
|
195
201
|
Examples:
|
196
202
|
|
@@ -220,16 +226,18 @@ example: inspec_tools xccdf2inspec -x xccdf_file.xml -a attributes.yml -o myprof
|
|
220
226
|
|
221
227
|
`inspec2xccdf` converts an InSpec profile in json format to a STIG XCCDF Document
|
222
228
|
|
229
|
+
See [examples documentation](./examples/inspec2xccdf/README.md) for additional guidance on usage including attribute details.
|
230
|
+
|
223
231
|
```
|
224
232
|
USAGE: inspec_tools inspec2xccdf [OPTIONS] -j <inspec-json> -a <xccdf-attr-yml> -o <xccdf-xml>
|
225
233
|
|
226
234
|
FLAGS:
|
227
235
|
-j --inspec-json <inspec-json> : path to InSpec Json file created using command 'inspec json <profile> > example.json'
|
228
|
-
-a --attributes <xccdf-attr-yml> : path to yml file that provides the required attributes for the XCCDF
|
229
|
-
-o --output <xccdf-xml> : name or path to create the
|
230
|
-
|
236
|
+
-a --attributes <xccdf-attr-yml> : path to yml file that provides the required attributes for the XCCDF document. These attributes are parts of XCCDF document which do not fit into the InSpec schema.
|
237
|
+
-o --output <xccdf-xml> : name or path to create the XCCDF and title to give the XCCDF
|
238
|
+
-m, [--metadata=METADATA] : path to json file with additional host metadata for the XCCDF file
|
231
239
|
|
232
|
-
example: inspec_tools inspec2xccdf -j
|
240
|
+
example: inspec_tools inspec2xccdf -j examples/sample_json/good_nginxresults.json -a lib/data/attributes.yml -o output.xccdf
|
233
241
|
```
|
234
242
|
|
235
243
|
## csv2inspec
|
@@ -295,7 +303,7 @@ FLAGS:
|
|
295
303
|
-s --separate-files [true | false] : output the resulting controls as multiple files (default: true) [optional]
|
296
304
|
-d --debug : debug run [optional]
|
297
305
|
|
298
|
-
example: inspec_tools pdf2inspec -p
|
306
|
+
example: inspec_tools pdf2inspec -p examples/CIS_Ubuntu_Linux_16.04_LTS_Benchmark_v1.0.0.pdf -o /path/to/myprofile -f ruby -s true
|
299
307
|
```
|
300
308
|
|
301
309
|
## xlsx2inspec
|
data/Rakefile
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require "rake/testtask"
|
1
|
+
require 'rake/testtask'
|
3
2
|
require File.expand_path('../lib/inspec_tools/version', __FILE__)
|
4
3
|
|
5
4
|
Rake::TestTask.new(:test) do |t|
|
6
|
-
t.libs <<
|
7
|
-
t.libs <<
|
5
|
+
t.libs << 'test'
|
6
|
+
t.libs << 'lib'
|
8
7
|
t.test_files = FileList['test/**/*_test.rb']
|
9
8
|
end
|
10
9
|
|
@@ -20,11 +19,86 @@ namespace :test do
|
|
20
19
|
'test/unit/inspec_tools_test.rb'
|
21
20
|
])
|
22
21
|
end
|
22
|
+
|
23
|
+
Rake::TestTask.new(:exclude_slow) do |t|
|
24
|
+
t.description = 'Excluding all tests that take more than 3 seconds to complete'
|
25
|
+
t.libs << 'test'
|
26
|
+
t.libs << "lib"
|
27
|
+
t.verbose = true
|
28
|
+
t.test_files = FileList['test/**/*_test.rb'].reject{|file| file.include? 'pdf_test.rb'}.reverse
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'Build for release'
|
33
|
+
task :build_release do
|
34
|
+
|
35
|
+
Rake::Task["generate_mapping_objects"].reenable
|
36
|
+
Rake::Task["generate_mapping_objects"].invoke
|
37
|
+
|
38
|
+
system('gem build inspec_tools.gemspec')
|
39
|
+
end
|
40
|
+
|
41
|
+
desc 'Generate mapping objects'
|
42
|
+
task :generate_mapping_objects do
|
43
|
+
require 'roo'
|
44
|
+
|
45
|
+
nist_mapping_cis_controls = ENV['NIST_MAPPING_CIS_CONTROLS'] || 'NIST_Map_02052020_CIS_Controls_Version_7.1_Implementation_Groups_1.2.xlsx'.freeze
|
46
|
+
nist_mapping_cis_critical_controls = ENV['NIST_MAPPING_CIS_CRITICAL_CONTROLS'] || 'NIST_Map_09212017B_CSC-CIS_Critical_Security_Controls_VER_6.1_Excel_9.1.2016.xlsx'.freeze
|
47
|
+
|
48
|
+
data_root_path = File.join(File.expand_path(__dir__), 'lib', 'data')
|
49
|
+
cis_controls_path = File.join(data_root_path, nist_mapping_cis_controls)
|
50
|
+
cis_critical_controls_path = File.join(data_root_path, nist_mapping_cis_critical_controls)
|
51
|
+
|
52
|
+
raise "#{cis_controls_path} does not exist" unless File.exist?(cis_controls_path)
|
53
|
+
|
54
|
+
raise "#{cis_critical_controls_path} does not exist" unless File.exist?(cis_critical_controls_path)
|
55
|
+
|
56
|
+
marshal_cis_controls(cis_controls_path, data_root_path)
|
57
|
+
marshal_cis_critical_controls(cis_critical_controls_path, data_root_path)
|
23
58
|
end
|
24
59
|
|
25
|
-
|
26
|
-
|
27
|
-
|
60
|
+
def marshal_cis_controls(cis_controls_path, data_root_path)
|
61
|
+
cis_to_nist = {}
|
62
|
+
Roo::Spreadsheet.open(cis_controls_path).sheet(3).each do |row|
|
63
|
+
if row[3].is_a?(Numeric)
|
64
|
+
cis_to_nist[row[3].to_s] = row[0]
|
65
|
+
else
|
66
|
+
cis_to_nist[row[2].to_s] = row[0] unless (row[2] == '') || row[2].to_i.nil?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
output_file = File.new(File.join(data_root_path, 'cis_to_nist_mapping'), 'w')
|
70
|
+
Marshal.dump(cis_to_nist, output_file)
|
71
|
+
output_file.close
|
28
72
|
end
|
29
73
|
|
30
|
-
|
74
|
+
def marshal_cis_critical_controls(cis_critical_controls_path, data_root_path)
|
75
|
+
controls_spreadsheet = Roo::Spreadsheet.open(cis_critical_controls_path)
|
76
|
+
controls_spreadsheet.default_sheet = 'VER 6.1 Controls'
|
77
|
+
headings = {}
|
78
|
+
controls_spreadsheet.row(3).each_with_index { |header, idx| headings[header] = idx }
|
79
|
+
|
80
|
+
nist_ver = 4
|
81
|
+
cis_ver = controls_spreadsheet.row(2)[4].split(' ')[-1]
|
82
|
+
control_count = 1
|
83
|
+
mapping = []
|
84
|
+
((controls_spreadsheet.first_row + 3)..controls_spreadsheet.last_row).each do |row_value|
|
85
|
+
current_row = {}
|
86
|
+
if controls_spreadsheet.row(row_value)[headings['NIST SP 800-53 Control #']].to_s != ''
|
87
|
+
current_row[:nist] = controls_spreadsheet.row(row_value)[headings['NIST SP 800-53 Control #']].to_s
|
88
|
+
else
|
89
|
+
current_row[:nist] = 'Not Mapped'
|
90
|
+
end
|
91
|
+
current_row[:nist_ver] = nist_ver
|
92
|
+
if controls_spreadsheet.row(row_value)[headings['Control']].to_s == ''
|
93
|
+
current_row[:cis] = control_count.to_s
|
94
|
+
control_count += 1
|
95
|
+
else
|
96
|
+
current_row[:cis] = controls_spreadsheet.row(row_value)[headings['Control']].to_s
|
97
|
+
end
|
98
|
+
current_row[:cis_ver] = cis_ver
|
99
|
+
mapping << current_row
|
100
|
+
end
|
101
|
+
output_file = File.new(File.join(data_root_path, 'cis_to_nist_critical_controls'), 'w')
|
102
|
+
Marshal.dump(mapping, output_file)
|
103
|
+
output_file.close
|
104
|
+
end
|
Binary file
|
Binary file
|
@@ -99,6 +99,88 @@ module HappyMapperTools
|
|
99
99
|
element :content, String, tag: 'check-content'
|
100
100
|
end
|
101
101
|
|
102
|
+
class MessageType
|
103
|
+
include HappyMapper
|
104
|
+
attribute :severity, String, tag: 'severity'
|
105
|
+
content :message, String
|
106
|
+
end
|
107
|
+
|
108
|
+
class RuleResultType
|
109
|
+
include HappyMapper
|
110
|
+
attribute :idref, String, tag: 'idref'
|
111
|
+
attribute :severity, String, tag: 'severity'
|
112
|
+
attribute :time, String, tag: 'time'
|
113
|
+
attribute :weight, String, tag: 'weight'
|
114
|
+
element :result, String, tag: 'result'
|
115
|
+
# element override - Not implemented. Does not apply to Inspec execution
|
116
|
+
has_many :ident, Ident, tag: 'ident'
|
117
|
+
# Note: element metadata not implemented at this time
|
118
|
+
has_many :message, MessageType, tag: 'message'
|
119
|
+
has_many :instance, String, tag: 'instance'
|
120
|
+
element :fix, Fix, tag: 'fix'
|
121
|
+
element :check, Check, tag: 'check'
|
122
|
+
end
|
123
|
+
|
124
|
+
class ScoreType
|
125
|
+
include HappyMapper
|
126
|
+
|
127
|
+
def initialize(system, maximum, score)
|
128
|
+
@system = system
|
129
|
+
@maximum = maximum
|
130
|
+
@score = score
|
131
|
+
end
|
132
|
+
|
133
|
+
attribute :system, String, tag: 'system'
|
134
|
+
attribute :maximum, String, tag: 'maximum' # optional attribute
|
135
|
+
content :score, String
|
136
|
+
end
|
137
|
+
|
138
|
+
class CPE2idrefType
|
139
|
+
include HappyMapper
|
140
|
+
attribute :idref, String, tag: 'idref'
|
141
|
+
end
|
142
|
+
|
143
|
+
class IdentityType
|
144
|
+
include HappyMapper
|
145
|
+
attribute :authenticated, Boolean, tag: 'authenticated'
|
146
|
+
attribute :privileged, Boolean, tag: 'privileged'
|
147
|
+
content :identity, String
|
148
|
+
end
|
149
|
+
|
150
|
+
class Fact
|
151
|
+
include HappyMapper
|
152
|
+
attribute :name, String, tag: 'name'
|
153
|
+
attribute :type, String, tag: 'type'
|
154
|
+
content :fact, String
|
155
|
+
end
|
156
|
+
|
157
|
+
class TargetFact
|
158
|
+
include HappyMapper
|
159
|
+
has_many :fact, Fact, tag: 'fact'
|
160
|
+
end
|
161
|
+
|
162
|
+
class TestResult
|
163
|
+
include HappyMapper
|
164
|
+
# Note: element benchmark not implemented at this time since this is same file
|
165
|
+
# Note: element title not implemented due to no mapping from Chef Inspec
|
166
|
+
element :remark, String, tag: 'remark'
|
167
|
+
has_many :organization, String, tag: 'organization'
|
168
|
+
element :identity, IdentityType, tag: 'identity'
|
169
|
+
element :target, String, tag: 'target'
|
170
|
+
has_many :target_address, String, tag: 'target-address'
|
171
|
+
element :target_facts, TargetFact, tag: 'target-facts'
|
172
|
+
element :platform, CPE2idrefType, tag: 'platform'
|
173
|
+
# Note: element profile not implemented since Benchmark profile is also not implemented
|
174
|
+
has_many :rule_result, RuleResultType, tag: 'rule-result'
|
175
|
+
has_many :score, ScoreType, tag: 'score' # One minimum
|
176
|
+
# Note: element signature not implemented due to no mapping from Chef Inspec
|
177
|
+
attribute :id, String, tag: 'id'
|
178
|
+
attribute :starttime, String, tag: 'start-time'
|
179
|
+
attribute :endtime, String, tag: 'end-time'
|
180
|
+
# Note: attribute test-system not implemented at this time due to unknown CPE value for Chef Inspec
|
181
|
+
attribute :version, String, tag: 'version'
|
182
|
+
end
|
183
|
+
|
102
184
|
# Class Profile maps from the 'Profile' from Benchmark XML file using HappyMapper
|
103
185
|
class Profile
|
104
186
|
include HappyMapper
|
@@ -156,6 +238,7 @@ module HappyMapperTools
|
|
156
238
|
element :version, String, tag: 'version'
|
157
239
|
has_many :profile, Profile, tag: 'Profile'
|
158
240
|
has_many :group, Group, tag: 'Group'
|
241
|
+
element :testresult, TestResult, tag: 'TestResult'
|
159
242
|
end
|
160
243
|
end
|
161
244
|
end
|
data/lib/inspec_tools/csv.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'csv'
|
2
|
-
require 'nokogiri'
|
3
|
-
require 'word_wrap'
|
4
2
|
require 'yaml'
|
5
3
|
require 'digest'
|
6
4
|
|
7
5
|
require_relative '../utilities/inspec_util'
|
6
|
+
require_relative '../utilities/cci_xml'
|
7
|
+
require_relative '../utilities/mapping_validator'
|
8
8
|
|
9
9
|
# rubocop:disable Metrics/AbcSize
|
10
10
|
# rubocop:disable Metrics/PerceivedComplexity
|
@@ -16,34 +16,25 @@ module InspecTools
|
|
16
16
|
def initialize(csv, mapping, name, verbose = false)
|
17
17
|
@name = name
|
18
18
|
@csv = csv
|
19
|
-
@mapping = mapping
|
19
|
+
@mapping = Utils::MappingValidator.validate(mapping)
|
20
20
|
@verbose = verbose
|
21
21
|
@csv.shift if @mapping['skip_csv_header']
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
25
|
-
# TODO
|
26
|
-
end
|
27
|
-
|
28
|
-
def to_xccdf
|
29
|
-
# TODO
|
30
|
-
end
|
31
|
-
|
32
|
-
def to_inspec
|
24
|
+
def to_inspec(control_name_prefix: nil)
|
33
25
|
@controls = []
|
34
|
-
@cci_xml = nil
|
35
26
|
@profile = {}
|
36
|
-
|
37
|
-
|
38
|
-
parse_controls
|
27
|
+
@cci_xml = Utils::CciXml.get_cci_list('U_CCI_List.xml')
|
28
|
+
insert_metadata
|
29
|
+
parse_controls(control_name_prefix)
|
39
30
|
@profile['controls'] = @controls
|
40
|
-
@profile['sha256'] = Digest::SHA256.hexdigest
|
31
|
+
@profile['sha256'] = Digest::SHA256.hexdigest(@profile.to_s)
|
41
32
|
@profile
|
42
33
|
end
|
43
34
|
|
44
35
|
private
|
45
36
|
|
46
|
-
def
|
37
|
+
def insert_metadata
|
47
38
|
@profile['name'] = @name
|
48
39
|
@profile['title'] = 'InSpec Profile'
|
49
40
|
@profile['maintainer'] = 'The Authors'
|
@@ -60,35 +51,37 @@ module InspecTools
|
|
60
51
|
}
|
61
52
|
end
|
62
53
|
|
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
54
|
def get_nist_reference(cci_number)
|
72
55
|
item_node = @cci_xml.xpath("//cci_list/cci_items/cci_item[@id='#{cci_number}']")[0] unless @cci_xml.nil?
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
77
|
-
[nist_ref, nist_ver]
|
56
|
+
return nil if item_node.nil?
|
57
|
+
|
58
|
+
[] << item_node.xpath('./references/reference[not(@version <= preceding-sibling::reference/@version) and not(@version <=following-sibling::reference/@version)]/@index').text
|
78
59
|
end
|
79
60
|
|
80
|
-
def
|
61
|
+
def get_cci_number(cell)
|
62
|
+
# Return nil if a mapping to the CCI was not provided or if there is not content in the CSV cell.
|
63
|
+
return nil if cell.nil? || @mapping['control.tags']['cci'].nil?
|
64
|
+
|
65
|
+
# If the content has been exported from STIG Viewer, the cell will have extra information
|
66
|
+
cell.split("\n").first
|
67
|
+
end
|
68
|
+
|
69
|
+
def parse_controls(prefix)
|
81
70
|
@csv.each do |row|
|
82
|
-
print '.'
|
83
71
|
control = {}
|
84
|
-
control['id'] = row[@mapping['control.id']]
|
85
|
-
control['title'] = row[@mapping['control.title']]
|
86
|
-
control['desc'] = row[@mapping['control.desc']]
|
72
|
+
control['id'] = generate_control_id(prefix, row[@mapping['control.id']]) unless @mapping['control.id'].nil? || row[@mapping['control.id']].nil?
|
73
|
+
control['title'] = row[@mapping['control.title']] unless @mapping['control.title'].nil? || row[@mapping['control.title']].nil?
|
74
|
+
control['desc'] = row[@mapping['control.desc']] unless @mapping['control.desc'].nil? || row[@mapping['control.desc']].nil?
|
87
75
|
control['tags'] = {}
|
88
|
-
|
89
|
-
|
76
|
+
cci_number = get_cci_number(row[@mapping['control.tags']['cci']])
|
77
|
+
nist = get_nist_reference(cci_number) unless cci_number.nil?
|
78
|
+
control['tags']['nist'] = nist unless nist.nil? || nist.include?(nil)
|
90
79
|
@mapping['control.tags'].each do |tag|
|
91
|
-
|
80
|
+
if tag.first == 'cci'
|
81
|
+
control['tags'][tag.first] = cci_number
|
82
|
+
next
|
83
|
+
end
|
84
|
+
control['tags'][tag.first] = row[tag.last] unless row[tag.last].nil?
|
92
85
|
end
|
93
86
|
unless @mapping['control.tags']['severity'].nil? || row[@mapping['control.tags']['severity']].nil?
|
94
87
|
control['impact'] = Utils::InspecUtil.get_impact(row[@mapping['control.tags']['severity']])
|
@@ -97,5 +90,15 @@ module InspecTools
|
|
97
90
|
@controls << control
|
98
91
|
end
|
99
92
|
end
|
93
|
+
|
94
|
+
def generate_control_id(prefix, id)
|
95
|
+
return id if prefix.nil?
|
96
|
+
|
97
|
+
"#{prefix}-#{id}"
|
98
|
+
end
|
100
99
|
end
|
101
100
|
end
|
101
|
+
|
102
|
+
# rubocop:enable Metrics/AbcSize
|
103
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
104
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module InspecTools
|
2
|
+
class GenerateMap
|
3
|
+
attr_accessor :text
|
4
|
+
|
5
|
+
def initialize(text = nil)
|
6
|
+
@text = text.nil? ? default_text : text
|
7
|
+
end
|
8
|
+
|
9
|
+
def generate_example(file)
|
10
|
+
File.write(file, @text)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def default_text
|
16
|
+
<<~YML
|
17
|
+
# Setting csv_header to true will skip the csv file header
|
18
|
+
skip_csv_header: true
|
19
|
+
width : 80
|
20
|
+
|
21
|
+
|
22
|
+
control.id: 0
|
23
|
+
control.title: 15
|
24
|
+
control.desc: 16
|
25
|
+
control.tags:
|
26
|
+
severity: 1
|
27
|
+
rid: 8
|
28
|
+
stig_id: 3
|
29
|
+
cci: 2
|
30
|
+
check: 12
|
31
|
+
fix: 10
|
32
|
+
YML
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|