85
85
def load_remediation_input (remediation_file ):
86
86
with open (remediation_file , mode = 'r' , encoding = "utf-8" ) as infile :
87
87
reader = csv .reader (infile )
88
- return {rows [0 ]:[rows [1 ],rows [2 ]] for rows in reader }
88
+ #return {rows[0]:[rows[1],rows[2]] for rows in reader}
89
+ return {rows [0 ]:rows [1 :] for rows in reader }
89
90
90
91
def remediation_is_valid (vuln , remediation_data ):
91
92
vulnerability_name = vuln ['vulnerabilityWithRemediation' ]['vulnerabilityName' ]
@@ -130,21 +131,26 @@ def set_vulnerablity_remediation(hub, vuln, remediation_status, remediation_comm
130
131
response = hub .execute_put (url , data = update )
131
132
return response
132
133
133
- def process_vulnerabilities (hub , vulnerable_components , remediation_data = None , exclusion_data = None ):
134
+ def process_vulnerabilities (hub , vulnerable_components , remediation_data = None , exclusion_data = None , dry_run = False ):
135
+
136
+ if (dry_run ):
137
+ print (f"Opening dry run output file: { dry_run } " )
138
+ csv_file = open (dry_run , mode = 'w' , newline = '' , encoding = 'utf-8' )
139
+ csv_writer = csv .writer (csv_file , delimiter = ',' , quotechar = '"' , quoting = csv .QUOTE_MINIMAL )
140
+
134
141
count = 0
135
142
print ('"Component Name","Component Version","CVE","Reason","Remeidation Status","HTTP response code"' )
136
143
137
144
for vuln in vulnerable_components ['items' ]:
138
145
if vuln ['vulnerabilityWithRemediation' ]['remediationStatus' ] == "NEW" :
146
+ remediation_action = None
147
+ exclusion_action = None
148
+
139
149
if (remediation_data ):
140
150
remediation_action = remediation_is_valid (vuln , remediation_data )
141
- else :
142
- remediation_action = None
143
151
144
152
if (exclusion_data ):
145
153
exclusion_action = origin_is_excluded (vuln , exclusion_data )
146
- else :
147
- exclusion_action = None
148
154
149
155
# If vuln has both a remdiation action and an origin exclusion action, set remdiation status
150
156
# to the remdiation action. Append the exclusion action's comment to the overall comment.
@@ -157,15 +163,20 @@ def process_vulnerabilities(hub, vulnerable_components, remediation_data=None, e
157
163
reason = 'origin-exclusion'
158
164
159
165
if (remediation_action ):
160
- resp = set_vulnerablity_remediation (hub , vuln , remediation_action [0 ],remediation_action [1 ])
161
- count += 1
166
+ if (dry_run ):
167
+ remediation_action .insert (0 , vuln ['vulnerabilityWithRemediation' ]['vulnerabilityName' ])
168
+ csv_writer .writerow (remediation_action )
169
+ else :
170
+ resp = set_vulnerablity_remediation (hub , vuln , remediation_action [0 ],remediation_action [1 ])
171
+ count += 1
172
+
162
173
print ('\" {}\" ,\" {}\" ,\" {}\" ,\" {}\" ,\" {}\" ,\" {}\" ' .
163
174
format (vuln ['componentName' ], vuln ['componentVersionName' ],
164
175
vuln ['vulnerabilityWithRemediation' ]['vulnerabilityName' ],
165
- reason , remediation_action [0 ], resp .status_code ))
176
+ reason , remediation_action [0 ], resp .status_code if not dry_run else "" ))
166
177
167
178
168
- print (f'Remediated { count } vulnerabilities.' )
179
+ print (f'Remediated { count } vulnerabilities. { "(dry run)" if dry_run else "" } ' )
169
180
170
181
def main (argv = None ): # IGNORE:C0111
171
182
'''Command line options.'''
@@ -178,7 +189,7 @@ def main(argv=None): # IGNORE:C0111
178
189
program_name = os .path .basename (sys .argv [0 ])
179
190
program_version = "v%s" % __version__
180
191
program_build_date = str (__updated__ )
181
- program_version_message = '%%(prog) s %s (%s)' % (program_version , program_build_date )
192
+ program_version_message = '%s %s (%s)' % (program_name , program_version , program_build_date )
182
193
program_shortdesc = __import__ ('__main__' ).__doc__ .split ("\n " )[1 ]
183
194
program_license = '''%s
184
195
@@ -199,6 +210,7 @@ def main(argv=None): # IGNORE:C0111
199
210
parser = ArgumentParser (description = program_license , formatter_class = RawDescriptionHelpFormatter )
200
211
parser .add_argument ("projectname" , help = "Project nname" )
201
212
parser .add_argument ("projectversion" , help = "Project vesrsion" )
213
+ parser .add_argument ("--dry-run" , dest = "dry_run" , nargs = '?' , const = "dry_run.csv" , help = "dry run" )
202
214
parser .add_argument ("--remediation-list" , dest = "local_remediation_list" , default = None , help = "Filename of cve remediation list csv file" )
203
215
parser .add_argument ("--origin-exclusion-list" , dest = "local_origin_exclusion_list" , default = None , help = "Filename of origin exclusion list csv file" )
204
216
parser .add_argument ("--no-process-cve-remediation-list" , dest = 'process_cve_remediation_list' , action = 'store_false' , help = "Disable processing CVE-Remediation-list" )
@@ -216,7 +228,11 @@ def main(argv=None): # IGNORE:C0111
216
228
local_origin_exclusion_file = args .local_origin_exclusion_list
217
229
process_cve_remediation = args .process_cve_remediation_list
218
230
process_origin_exclulsion = args .process_origin_exclusion_list
219
-
231
+ #dry_run = args.dry_run
232
+ #dry_run_output = args.dry_run_output
233
+ dry_run = args .dry_run
234
+ print (args .dry_run )
235
+
220
236
message = f"{ program_version_message } \n \n Project: { projectname } \n Version: { projectversion } \n Process origin exclusion list: { process_origin_exclulsion } \n Process CVE remediation list: { process_cve_remediation } "
221
237
print (message )
222
238
@@ -258,7 +274,7 @@ def main(argv=None): # IGNORE:C0111
258
274
# Retrieve the vulnerabiltites for the project version
259
275
vulnerable_components = hub .get_vulnerable_bom_components (version )
260
276
261
- process_vulnerabilities (hub , vulnerable_components , remediation_data , exclusion_data )
277
+ process_vulnerabilities (hub , vulnerable_components , remediation_data , exclusion_data , dry_run )
262
278
263
279
return 0
264
280
except Exception :
0 commit comments