@@ -226,6 +226,7 @@ def resolve_env(self):
226
226
227
227
def resolve_ver (self ):
228
228
env = self .env or 'default'
229
+ print ("self.ver_id: " , self .ver_id )
229
230
if not self .ver_id :
230
231
for product in self .data .get ('data' , {}).get ('organization' , {}).get ('productNodes' , {}).get ('products' , []):
231
232
if product ['id' ] == self .prod_id :
@@ -252,6 +253,46 @@ def resolve_ver(self):
252
253
253
254
return (empty_ver or self .ver ) and self .ver_id
254
255
256
+ def resolve_latest_ver (self ):
257
+ """
258
+ Resolve and set the version ID for the latest uploaded SBOM version
259
+ based on the most recent updatedAt timestamp.
260
+ """
261
+ # fetch the context data
262
+ self .data = self ._fetch_context ()
263
+ if not self .data :
264
+ print ("Failed to refresh context data" )
265
+ return False
266
+
267
+ print ("Attempting to resolve the latest version information for Product ID:" , self .prod_id , "Environment ID:" , self .env_id )
268
+
269
+ # retry to handle propagation delays
270
+ for attempt in range (5 ):
271
+ print (f"Attempt { attempt + 1 } : Resolving the latest version ID based on updatedAt" )
272
+
273
+ for product in self .data .get ('data' , {}).get ('organization' , {}).get ('productNodes' , {}).get ('products' , []):
274
+ if product ['id' ] == self .prod_id :
275
+ for env in product ['environments' ]:
276
+ if env ['id' ] == self .env_id :
277
+
278
+ # sort the versions by updatedAt in descending order
279
+ versions_sorted = sorted (env ['versions' ], key = lambda v : v ['updatedAt' ], reverse = True )
280
+ latest_version = versions_sorted [0 ] if versions_sorted else None
281
+
282
+ if latest_version :
283
+ self .ver_id = latest_version ['id' ]
284
+ self .ver = latest_version ['primaryComponent' ]['version' ]
285
+ self .ver_status = self .vuln_status_to_status (latest_version ['vulnRunStatus' ])
286
+ print (f"Resolved version ID: { self .ver_id } " )
287
+ return True
288
+
289
+ print ("Latest version ID not found. Retrying..." )
290
+ time .sleep (2 )
291
+
292
+ print ("Error: Unable to resolve the latest SBOM version information after multiple attempts." )
293
+ return False
294
+
295
+
255
296
def __repr__ (self ):
256
297
from pprint import pformat
257
298
return pformat (vars (self ), indent = 1 , width = 1 )
@@ -286,6 +327,7 @@ def versions(self):
286
327
287
328
def status (self ):
288
329
self .resolve_ver ()
330
+ print ("self.ver_status: " , self .ver_status )
289
331
return self .ver_status
290
332
291
333
def download (self ):
@@ -334,17 +376,17 @@ def download(self):
334
376
response .status_code )
335
377
336
378
def upload (self , sbom_file ):
337
- if os .path .isfile (sbom_file ) is False :
379
+ if not os .path .isfile (sbom_file ):
338
380
print (f"SBOM File not found: { sbom_file } " )
339
- return
381
+ return None
340
382
341
383
if not self .prod_id :
342
384
print (f"Product not found: { self .prod } " )
343
- return
385
+ return None
344
386
345
387
if not self .env_id :
346
388
print (f"Environment not found: { self .env } " )
347
- return
389
+ return None
348
390
349
391
logging .debug ("Uploading SBOM to product ID %s" , self .prod_id )
350
392
@@ -367,26 +409,66 @@ def upload(self, sbom_file):
367
409
with open (sbom_file , 'rb' ) as sbom :
368
410
files_map = {'0' : sbom }
369
411
response = requests .post (self .api_url ,
370
- headers = headers ,
371
- data = form_data ,
372
- files = files_map ,
373
- timeout = INTERLYNK_API_TIMEOUT )
412
+ headers = headers ,
413
+ data = form_data ,
414
+ files = files_map ,
415
+ timeout = INTERLYNK_API_TIMEOUT )
374
416
if response .status_code == 200 :
375
417
resp_json = response .json ()
376
- errors = resp_json .get ('data' , {}).get (
377
- 'sbomUpload' , {}).get ('errors' )
418
+ errors = resp_json .get ('data' , {}).get ('sbomUpload' , {}).get ('errors' )
378
419
if errors :
379
420
print (f"Error uploading sbom: { errors } " )
380
- return 1
421
+ return None
422
+
381
423
print ('Uploaded successfully' )
382
424
logging .debug ("SBOM Uploading response: %s" , response .text )
383
- return 0
425
+ return True # Return True to indicate a successful upload
426
+
384
427
logging .error ("Error uploading sbom: %d" , response .status_code )
385
428
except requests .exceptions .RequestException as ex :
386
429
logging .error ("RequestException: %s" , ex )
387
430
except FileNotFoundError as ex :
388
431
logging .error ("FileNotFoundError: %s" , ex )
389
- return 1
432
+
433
+ return None
434
+
435
+
436
+ def _fetch_latest_version_id (self ):
437
+ """
438
+ Fetch the latest version ID for the current product and environment.
439
+ """
440
+ headers = {
441
+ "Authorization" : "Bearer " + self .token
442
+ }
443
+
444
+ request_data = {
445
+ "query" : QUERY_PRODUCTS_LIST ,
446
+ "variables" : {"first" : 1 }, # Fetch the latest
447
+ }
448
+
449
+ try :
450
+ response = requests .post (self .api_url ,
451
+ headers = headers ,
452
+ json = request_data ,
453
+ timeout = INTERLYNK_API_TIMEOUT )
454
+ if response .status_code == 200 :
455
+ response_data = response .json ()
456
+ products = response_data .get ('data' , {}).get ('organization' , {}).get ('productNodes' , {}).get ('products' , [])
457
+ for product in products :
458
+ if product ['id' ] == self .prod_id :
459
+ for env in product ['environments' ]:
460
+ if env ['id' ] == self .env_id :
461
+ # Assuming the latest version is at the end of the list
462
+ latest_version = env ['versions' ][- 1 ]
463
+ return latest_version ['id' ] if latest_version else None
464
+
465
+ logging .error ("Error: Version ID not found for the specified product and environment." )
466
+ else :
467
+ logging .error ("Failed to retrieve latest version ID. Status code: %s" , response .status_code )
468
+ except requests .exceptions .RequestException as ex :
469
+ logging .error ("RequestException: %s" , ex )
470
+ return None
471
+
390
472
391
473
def vuln_status_to_status (self , status ):
392
474
result_dict = dict ()
@@ -396,18 +478,21 @@ def vuln_status_to_status(self, status):
396
478
result_dict ['automationStatus' ] = 'UNKNOWN'
397
479
result_dict ['vulnScanStatus' ] = 'UNKNOWN'
398
480
if status == 'NOT_STARTED' :
481
+ print ("NOT_STARTED" )
399
482
result_dict ['vulnScanStatus' ] = 'NOT_STARTED'
400
483
result_dict ['checksStatus' ] = 'NOT_STARTED'
401
484
result_dict ['policyStatus' ] = 'NOT_STARTED'
402
485
result_dict ['labelingStatus' ] = 'NOT_STARTED'
403
486
result_dict ['automationStatus' ] = 'NOT_STARTED'
404
487
elif status == 'IN_PROGRESS' :
488
+ print ("IN_PROGRESS" )
405
489
result_dict ['vulnScanStatus' ] = 'IN_PROGRESS'
406
490
result_dict ['checksStatus' ] = 'COMPLETED'
407
491
result_dict ['policyStatus' ] = 'COMPLETED'
408
492
result_dict ['labelingStatus' ] = 'COMPLETED'
409
493
result_dict ['automationStatus' ] = 'COMPLETED'
410
494
elif status == 'FINISHED' :
495
+ print ("FINISHED" )
411
496
result_dict ['vulnScanStatus' ] = 'COMPLETED'
412
497
result_dict ['checksStatus' ] = 'COMPLETED'
413
498
result_dict ['policyStatus' ] = 'COMPLETED'
0 commit comments