8585def load_remediation_input (remediation_file ):
8686 with open (remediation_file , mode = 'r' , encoding = "utf-8" ) as infile :
8787 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 }
8990
9091def remediation_is_valid (vuln , remediation_data ):
9192 vulnerability_name = vuln ['vulnerabilityWithRemediation' ]['vulnerabilityName' ]
@@ -130,21 +131,26 @@ def set_vulnerablity_remediation(hub, vuln, remediation_status, remediation_comm
130131 response = hub .execute_put (url , data = update )
131132 return response
132133
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+
134141 count = 0
135142 print ('"Component Name","Component Version","CVE","Reason","Remeidation Status","HTTP response code"' )
136143
137144 for vuln in vulnerable_components ['items' ]:
138145 if vuln ['vulnerabilityWithRemediation' ]['remediationStatus' ] == "NEW" :
146+ remediation_action = None
147+ exclusion_action = None
148+
139149 if (remediation_data ):
140150 remediation_action = remediation_is_valid (vuln , remediation_data )
141- else :
142- remediation_action = None
143151
144152 if (exclusion_data ):
145153 exclusion_action = origin_is_excluded (vuln , exclusion_data )
146- else :
147- exclusion_action = None
148154
149155 # If vuln has both a remdiation action and an origin exclusion action, set remdiation status
150156 # 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
157163 reason = 'origin-exclusion'
158164
159165 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+
162173 print ('\" {}\" ,\" {}\" ,\" {}\" ,\" {}\" ,\" {}\" ,\" {}\" ' .
163174 format (vuln ['componentName' ], vuln ['componentVersionName' ],
164175 vuln ['vulnerabilityWithRemediation' ]['vulnerabilityName' ],
165- reason , remediation_action [0 ], resp .status_code ))
176+ reason , remediation_action [0 ], resp .status_code if not dry_run else "" ))
166177
167178
168- print (f'Remediated { count } vulnerabilities.' )
179+ print (f'Remediated { count } vulnerabilities. { "(dry run)" if dry_run else "" } ' )
169180
170181def main (argv = None ): # IGNORE:C0111
171182 '''Command line options.'''
@@ -178,7 +189,7 @@ def main(argv=None): # IGNORE:C0111
178189 program_name = os .path .basename (sys .argv [0 ])
179190 program_version = "v%s" % __version__
180191 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 )
182193 program_shortdesc = __import__ ('__main__' ).__doc__ .split ("\n " )[1 ]
183194 program_license = '''%s
184195
@@ -199,6 +210,7 @@ def main(argv=None): # IGNORE:C0111
199210 parser = ArgumentParser (description = program_license , formatter_class = RawDescriptionHelpFormatter )
200211 parser .add_argument ("projectname" , help = "Project nname" )
201212 parser .add_argument ("projectversion" , help = "Project vesrsion" )
213+ parser .add_argument ("--dry-run" , dest = "dry_run" , nargs = '?' , const = "dry_run.csv" , help = "dry run" )
202214 parser .add_argument ("--remediation-list" , dest = "local_remediation_list" , default = None , help = "Filename of cve remediation list csv file" )
203215 parser .add_argument ("--origin-exclusion-list" , dest = "local_origin_exclusion_list" , default = None , help = "Filename of origin exclusion list csv file" )
204216 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
216228 local_origin_exclusion_file = args .local_origin_exclusion_list
217229 process_cve_remediation = args .process_cve_remediation_list
218230 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+
220236 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 } "
221237 print (message )
222238
@@ -258,7 +274,7 @@ def main(argv=None): # IGNORE:C0111
258274 # Retrieve the vulnerabiltites for the project version
259275 vulnerable_components = hub .get_vulnerable_bom_components (version )
260276
261- process_vulnerabilities (hub , vulnerable_components , remediation_data , exclusion_data )
277+ process_vulnerabilities (hub , vulnerable_components , remediation_data , exclusion_data , dry_run )
262278
263279 return 0
264280 except Exception :
0 commit comments