diff --git a/modules/ingestor/src/service/advisory/csaf/loader.rs b/modules/ingestor/src/service/advisory/csaf/loader.rs index 1ccff548..903b6f83 100644 --- a/modules/ingestor/src/service/advisory/csaf/loader.rs +++ b/modules/ingestor/src/service/advisory/csaf/loader.rs @@ -7,12 +7,13 @@ use crate::{ Graph, }, model::IngestResult, - service::{advisory::csaf::PurlStatusCreator, Error}, + service::{advisory::csaf::PurlStatusCreator, Error, Warnings}, }; use csaf::{ vulnerability::{ProductStatus, Vulnerability}, Csaf, }; +use sbom_walker::report::ReportSink; use std::{io::Read, str::FromStr}; use time::OffsetDateTime; use tracing::{info_span, instrument}; @@ -57,6 +58,8 @@ impl<'g> CsafLoader<'g> { document: R, digests: &Digests, ) -> Result { + let warnings = Warnings::new(); + let csaf: Csaf = info_span!("parse document").in_scope(|| serde_json::from_reader(document))?; @@ -71,7 +74,7 @@ impl<'g> CsafLoader<'g> { .await?; for vuln in csaf.vulnerabilities.iter().flatten() { - self.ingest_vulnerability(&csaf, &advisory, vuln, &tx) + self.ingest_vulnerability(&csaf, &advisory, vuln, &warnings, &tx) .await?; } @@ -80,7 +83,7 @@ impl<'g> CsafLoader<'g> { Ok(IngestResult { id: Id::Uuid(advisory.advisory.id), document_id: advisory_id, - warnings: vec![], + warnings: warnings.into(), }) } @@ -95,6 +98,7 @@ impl<'g> CsafLoader<'g> { csaf: &Csaf, advisory: &AdvisoryContext<'_>, vulnerability: &Vulnerability, + report: &dyn ReportSink, tx: TX, ) -> Result<(), Error> { if let Some(cve_id) = &vulnerability.cve { @@ -124,19 +128,19 @@ impl<'g> CsafLoader<'g> { .await?; } - if let Some(scores) = &vulnerability.scores { - for score in scores { - if let Some(v3) = &score.cvss_v3 { - match Cvss3Base::from_str(&v3.to_string()) { - Ok(cvss3) => { - log::debug!("{cvss3:?}"); - advisory_vulnerability - .ingest_cvss3_score(cvss3, &tx) - .await?; - } - Err(err) => { - log::warn!("Unable to parse CVSS3: {:#?}", err); - } + for score in vulnerability.scores.iter().flatten() { + if let Some(v3) = &score.cvss_v3 { + match Cvss3Base::from_str(&v3.to_string()) { + Ok(cvss3) => { + log::debug!("{cvss3:?}"); + advisory_vulnerability + .ingest_cvss3_score(cvss3, &tx) + .await?; + } + Err(err) => { + let msg = format!("Unable to parse CVSS3: {:#?}", err); + log::info!("{msg}"); + report.error(msg); } } } diff --git a/modules/ingestor/src/service/advisory/osv/loader.rs b/modules/ingestor/src/service/advisory/osv/loader.rs index 73599553..2bbff872 100644 --- a/modules/ingestor/src/service/advisory/osv/loader.rs +++ b/modules/ingestor/src/service/advisory/osv/loader.rs @@ -1,5 +1,6 @@ use crate::graph::advisory::advisory_vulnerability::{Version, VersionInfo, VersionSpec}; use crate::model::IngestResult; +use crate::service::Warnings; use crate::{ graph::{ advisory::{AdvisoryInformation, AdvisoryVulnerabilityInformation}, @@ -8,6 +9,7 @@ use crate::{ service::{advisory::osv::translate, Error}, }; use osv::schema::{Event, ReferenceType, SeverityType, Vulnerability}; +use sbom_walker::report::ReportSink; use std::{io::Read, str::FromStr, sync::OnceLock}; use trustify_common::hashing::Digests; use trustify_common::id::Id; @@ -31,6 +33,8 @@ impl<'g> OsvLoader<'g> { digests: &Digests, issuer: Option, ) -> Result { + let warnings = Warnings::new(); + let osv: Vulnerability = serde_json::from_reader(record)?; let labels = labels.into().add("type", "osv"); @@ -88,7 +92,9 @@ impl<'g> OsvLoader<'g> { advisory_vuln.ingest_cvss3_score(cvss3, &tx).await?; } Err(err) => { - log::warn!("Unable to parse CVSS3: {:#?}", err); + let msg = format!("Unable to parse CVSS3: {:#?}", err); + log::info!("{msg}"); + warnings.error(msg) } } } @@ -191,7 +197,7 @@ impl<'g> OsvLoader<'g> { Ok(IngestResult { id: Id::Uuid(advisory.advisory.id), document_id: osv.id, - warnings: vec![], + warnings: warnings.into(), }) } } diff --git a/modules/ingestor/src/service/mod.rs b/modules/ingestor/src/service/mod.rs index e3dc8517..e86daef3 100644 --- a/modules/ingestor/src/service/mod.rs +++ b/modules/ingestor/src/service/mod.rs @@ -148,6 +148,12 @@ impl IngestorService { #[derive(Default)] pub(crate) struct Warnings(Arc>>); +impl Warnings { + pub fn new() -> Self { + Self::default() + } +} + impl ReportSink for Warnings { fn error(&self, msg: String) { self.0.lock().push(msg);