@@ -106,9 +106,9 @@ class DataSource(ContextManager):
106106 def __init__ (
107107 self ,
108108 batch_size : int ,
109- last_run_date : Optional [datetime ]= None ,
110- cutoff_date : Optional [datetime ]= None ,
111- config : Optional [Mapping [str , Any ]]= None ,
109+ last_run_date : Optional [datetime ] = None ,
110+ cutoff_date : Optional [datetime ] = None ,
111+ config : Optional [Mapping [str , Any ]] = None ,
112112 ):
113113 """
114114 Create a DataSource instance.
@@ -240,9 +240,9 @@ def __exit__(self, exc_type, exc_val, exc_tb):
240240
241241 def file_changes (
242242 self ,
243- subdir : str = None ,
244- recursive : bool = False ,
245- file_ext : Optional [str ]= None ,
243+ subdir : str = None ,
244+ recursive : bool = False ,
245+ file_ext : Optional [str ] = None ,
246246 ) -> Tuple [Set [str ], Set [str ]]:
247247 """
248248 Returns all added and modified files since last_run_date or cutoff_date (whichever is more
@@ -382,9 +382,9 @@ def _update_from_remote(self, remote, branch) -> None:
382382
383383def _include_file (
384384 path : str ,
385- subdir : Optional [str ]= None ,
386- recursive : bool = False ,
387- file_ext : Optional [str ]= None ,
385+ subdir : Optional [str ] = None ,
386+ recursive : bool = False ,
387+ file_ext : Optional [str ] = None ,
388388) -> bool :
389389 match = True
390390
@@ -408,7 +408,6 @@ class OvalDataSource(DataSource):
408408 All data sources which collect data from OVAL files must inherit from this
409409 `OvalDataSource` class. Subclasses must implement the methods `_fetch` and `set_api`.
410410 """
411-
412411 @staticmethod
413412 def create_purl (pkg_name : str , pkg_version : str , pkg_data : Mapping ) -> PackageURL :
414413 """
@@ -434,48 +433,29 @@ def _collect_pkgs(parsed_oval_data: Mapping) -> Set:
434433
435434 def _fetch (self ) -> Tuple [Mapping , Iterable [ET .ElementTree ]]:
436435 """
437- Return a two-tuple of ({mapping of Package URL data}, it's ET.ElementTree)
436+ This method contains logic to fetch OVAL files and yield them into
437+ a tuple of file's metadata and it's ET.ElementTree.
438438 Subclasses must implement this method.
439439
440- Note: Package URL data MUST INCLUDE a Package URL "type" key so
441- implement _fetch() accordingly.
442- For example::
443-
440+ Note: Mapping MUST INCLUDE "type" key. Example values of Mapping
444441 {"type":"deb","qualifiers":{"distro":"buster"} }
442+
445443 """
446- # TODO: enforce that we receive the proper data here
447444 raise NotImplementedError
448445
449446 def updated_advisories (self ) -> List [Advisory ]:
450- for purl_data , oval_etree in self ._fetch ():
451- if 'type' not in purl_data :
452- ets = (oval_etree and ET .tostring (oval_etree )) or 'NO DATA'
453- msg = (
454- "Failed to get updated_advisories for Ubuntu: purl_data is "
455- f"missing a package type { purl_data !r} \n "
456- f"with OVAL XML:\n "
457- f"{ ets } \n "
458- f"... continuing..."
459- )
460- print (msg )
461- logger .error (msg )
462- continue
463-
447+ """
448+ Note: metadata MUST INCLUDE "type" key, implement _fetch accordingly.
449+ """
450+ for metadata , oval_file in self ._fetch ():
464451 try :
465- oval_data = self .get_data_from_xml_doc (oval_etree , purl_data )
452+ oval_data = self .get_data_from_xml_doc (oval_file , metadata )
466453 yield oval_data
467454 except Exception :
468- ets = (oval_etree and ET .tostring (oval_etree )) or 'NO DATA'
469- tb = traceback .format_exc ()
470- msg = (
471- f"Failed to get updated_advisories for Ubuntu:"
472- f"with { purl_data !r} \n "
473- f"and with OVAL XML:\n "
474- f"{ ets } \n { tb } \n "
475- f"... continuing..."
455+ logger .error (
456+ f"Failed to get updated_advisories: { oval_file !r} "
457+ "with {metadata!r}:\n " + traceback .format_exc ()
476458 )
477- print (msg )
478- logger .error (msg )
479459 continue
480460
481461 def set_api (self , all_pkgs : Iterable [str ]):
@@ -493,89 +473,57 @@ def set_api(self, all_pkgs: Iterable[str]):
493473
494474 def get_data_from_xml_doc (self , xml_doc : ET .ElementTree , pkg_metadata = {}) -> List [Advisory ]:
495475 """
496- The orchestration method of the OvalDataSource. This method breaks an
497- OVAL xml ElementTree into a list of `Advisory`.
476+ The orchestration method of the OvalDataSource. This method breaks an OVAL xml
477+ ElementTree into a list of `Advisory`.
498478
499- Note: pkg_metadata is a mapping of Package URL data that MUST INCLUDE
500- "type" key.
501-
502- Example value of pkg_metadata:
479+ Note: pkg_metadata MUST INCLUDE "type" key. Example value of pkg_metadata,
503480 {"type":"deb","qualifiers":{"distro":"buster"} }
504481 """
505- if 'type' not in pkg_metadata :
506- ets = xml_doc and ET .tostring (xml_doc ) or 'NO DATA'
507- msg = (
508- "Failed to get_data_from_xml_doc: pkg_metadata is "
509- f"missing a package type { pkg_metadata !r} \n "
510- f"with OVAL XML:\n "
511- f"{ ets } "
512- )
513- print (msg )
514- logger .error (msg )
515- raise Exception (msg )
516-
517482 all_adv = []
518483 oval_doc = OvalParser (self .translations , xml_doc )
519- try :
520- raw_data = oval_doc .get_data ()
521- except Exception :
522- ets = xml_doc and ET .tostring (xml_doc ) or 'NO DATA'
523- tb = traceback .format_exc ()
524- msg = (
525- f"Failed to get_data_from_xml_doc:"
526- f"with { pkg_metadata !r} \n "
527- f"and with OVAL XML:\n "
528- f"{ ets } \n { tb } "
529- )
530- print (msg )
531- logger .error (msg )
532- raise Exception (msg )
533-
484+ raw_data = oval_doc .get_data ()
534485 all_pkgs = self ._collect_pkgs (raw_data )
535486 self .set_api (all_pkgs )
487+ for definition_data in raw_data : # definition_data -> Advisory
536488
537- # convert definition_data to Advisory objects
538- for definition_data in raw_data :
539- # These fields are definition level, i.e common for all elements
540- # connected/linked to an OvalDefinition
489+ # These fields are definition level, i.e common for all
490+ # elements connected/linked to an OvalDefinition
541491 vuln_id = definition_data ['vuln_id' ]
542492 description = definition_data ['description' ]
543493 affected_purls = set ()
544494 safe_purls = set ()
545- references = [Reference (url = url ) for url in definition_data ['reference_urls' ]]
495+ references = [Reference (url = url )
496+ for url in definition_data ['reference_urls' ]]
497+
546498 for test_data in definition_data ['test_data' ]:
547499 for package in test_data ['package_list' ]:
548500 pkg_name = package
549501 if package and len (pkg_name ) >= 50 :
550502 continue
551- aff_ver_range = test_data ['version_ranges' ] or set ()
503+ aff_ver_range = test_data ['version_ranges' ]
552504 all_versions = self .pkg_manager_api .get (package )
553-
554- # FIXME: what is this 50 DB limit? that's too small for versions
555- # FIXME: we should not drop data this way
556505 # This filter is for filtering out long versions.
557506 # 50 is limit because that's what db permits atm.
558- all_versions = set (filter (lambda x : len (x ) < 50 , all_versions ))
507+ all_versions = set (
508+ filter (
509+ lambda x : len (x ) < 50 ,
510+ all_versions ))
559511 if not all_versions :
560512 continue
561-
562- affected_versions = set (filter (lambda x : x in aff_ver_range , all_versions ))
513+ affected_versions = set (
514+ filter (
515+ lambda x : x in aff_ver_range ,
516+ all_versions ))
563517 safe_versions = all_versions - affected_versions
564518
565519 for version in affected_versions :
566520 pkg_url = self .create_purl (
567- pkg_name = pkg_name ,
568- pkg_version = version ,
569- pkg_data = pkg_metadata ,
570- )
521+ pkg_name = pkg_name , pkg_version = version , pkg_data = pkg_metadata )
571522 affected_purls .add (pkg_url )
572523
573524 for version in safe_versions :
574525 pkg_url = self .create_purl (
575- pkg_name = pkg_name ,
576- pkg_version = version ,
577- pkg_data = pkg_metadata ,
578- )
526+ pkg_name = pkg_name , pkg_version = version , pkg_data = pkg_metadata )
579527 safe_purls .add (pkg_url )
580528
581529 all_adv .append (
@@ -584,8 +532,5 @@ def get_data_from_xml_doc(self, xml_doc: ET.ElementTree, pkg_metadata={}) -> Lis
584532 impacted_package_urls = affected_purls ,
585533 resolved_package_urls = safe_purls ,
586534 cve_id = vuln_id ,
587- vuln_references = references ,
588- ))
589-
590- print (f"Processed { len (all_adv )} Advisory from Oval data for { pkg_metadata } " )
535+ vuln_references = references ))
591536 return all_adv
0 commit comments