@@ -98,7 +98,7 @@ def __init__(self, importer: models.Importer, batch_size: int):
9898 self .importer = importer
9999 self .batch_size = batch_size
100100
101- def run (self , cutoff_date : datetime .datetime = None ) -> None :
101+ def run (self , create_vulcodes = True , cutoff_date : datetime .datetime = None ) -> None :
102102 """
103103 Create a data source for the given importer and store the data retrieved in the database.
104104
@@ -112,7 +112,7 @@ def run(self, cutoff_date: datetime.datetime = None) -> None:
112112 logger .info (f"Starting import for { self .importer .name } ." )
113113 data_source = self .importer .make_data_source (self .batch_size , cutoff_date = cutoff_date )
114114 with data_source :
115- process_advisories (data_source )
115+ process_advisories (data_source , create_vulcodes )
116116 self .importer .last_run = datetime .datetime .now (tz = datetime .timezone .utc )
117117 self .importer .data_source_cfg = dataclasses .asdict (data_source .config )
118118 self .importer .save ()
@@ -133,7 +133,7 @@ def get_vuln_pkg_refs(vulnerability, package):
133133 )
134134
135135
136- def process_advisories (data_source : DataSource ) -> None :
136+ def process_advisories (data_source : DataSource , create_vulcodes ) -> None :
137137 bulk_create_vuln_refs = set ()
138138 bulk_create_vuln_pkg_refs = set ()
139139 # Treat updated_advisories and added_advisories as same. Eventually
@@ -143,6 +143,9 @@ def process_advisories(data_source: DataSource) -> None:
143143 for batch in advisory_batches :
144144 for advisory in batch :
145145 try :
146+ if not advisory .identifier and not create_vulcodes :
147+ continue
148+
146149 vuln , vuln_created = _get_or_create_vulnerability (advisory )
147150 for vuln_ref in advisory .vuln_references :
148151 ref = VulnerabilityReferenceInserter (
@@ -151,11 +154,9 @@ def process_advisories(data_source: DataSource) -> None:
151154 reference_id = vuln_ref .reference_id ,
152155 )
153156
154- if vuln_created or not vuln_ref_exists (
155- vuln , vuln_ref .url , vuln_ref .reference_id
156- ):
157- # A vulnerability reference can't exist if the
158- # vulnerability is just created so insert it
157+ if vuln_created or not vuln_ref_exists (vuln , vuln_ref .url , vuln_ref .reference_id ):
158+ # A vulnerability reference can't exist if the vulnerability is just created so
159+ # insert it
159160 bulk_create_vuln_refs .add (ref )
160161
161162 for purl in chain (advisory .impacted_package_urls , advisory .resolved_package_urls ):
@@ -175,12 +176,20 @@ def process_advisories(data_source: DataSource) -> None:
175176 existing_ref = get_vuln_pkg_refs (vuln , pkg )
176177 if not existing_ref :
177178 bulk_create_vuln_pkg_refs .add (pkg_vuln_ref )
179+ # A vulnerability-package relationship does not exist already if either the
180+ # vulnerability or the package is just created.
178181
179182 else :
180- # This handles conflicts between existing data and obtained data
181- if existing_ref [0 ].is_vulnerable != pkg_vuln_ref .is_vulnerable :
182- handle_conflicts ([existing_ref [0 ], pkg_vuln_ref .to_model_object ()])
183- existing_ref .delete ()
183+ # insert only if it there is no existing vulnerability-package relationship.
184+ existing_ref = get_vuln_pkg_refs (vuln , pkg )
185+ if not existing_ref :
186+ bulk_create_vuln_pkg_refs .add (pkg_vuln_ref )
187+
188+ else :
189+ # This handles conflicts between existing data and obtained data
190+ if existing_ref [0 ].is_vulnerable != pkg_vuln_ref .is_vulnerable :
191+ handle_conflicts ([existing_ref [0 ], pkg_vuln_ref .to_model_object ()])
192+ existing_ref .delete ()
184193 except Exception :
185194 # TODO: store error but continue
186195 logger .error (
@@ -249,20 +258,13 @@ def handle_conflicts(conflicts):
249258def _get_or_create_vulnerability (
250259 advisory : Advisory ,
251260) -> Tuple [models .Vulnerability , bool ]:
252- if advisory .identifier :
253- query_kwargs = {"identifier" : advisory .identifier }
254- elif advisory .summary :
255- query_kwargs = {"summary" : advisory .summary }
256- else :
257- return models .Vulnerability .objects .create (), True
258-
259- try :
260- vuln , created = models .Vulnerability .objects .get_or_create (** query_kwargs )
261- # Eventually we only want to keep summary from NVD and ignore other descriptions.
262- if advisory .summary and vuln .summary != advisory .summary :
263- vuln .summary = advisory .summary
264- vuln .save ()
265- return vuln , created
261+
262+ vuln , created = models .Vulnerability .objects .get_or_create (identifier = advisory .identifier )
263+
264+ # Eventually we only want to keep summary from NVD and ignore other descriptions.
265+ if advisory .summary and vuln .summary != advisory .summary :
266+ vuln .summary = advisory .summary
267+ vuln .save ()
266268
267269 except Exception :
268270 logger .error (
0 commit comments