From fcc0029c886120f12ec7fb50e3bb01170ebf4cf0 Mon Sep 17 00:00:00 2001 From: Fede Barcelona Date: Tue, 28 Oct 2025 09:04:39 +0100 Subject: [PATCH 1/2] feat(scanresult): Use global evaluation result from scanner --- .pre-commit-config.yaml | 2 + src/domain/scanresult/evaluation_result.rs | 10 +++++ src/domain/scanresult/scan_result.rs | 39 +++++++++++++------ ...ysdig_image_scanner_json_scan_result_v1.rs | 15 +++---- tests/general.rs | 2 + 5 files changed, 47 insertions(+), 21 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5123057..68df062 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,3 +12,5 @@ repos: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml + - id: check-toml + - id: no-commit-to-branch diff --git a/src/domain/scanresult/evaluation_result.rs b/src/domain/scanresult/evaluation_result.rs index c1240d5..74aebb7 100644 --- a/src/domain/scanresult/evaluation_result.rs +++ b/src/domain/scanresult/evaluation_result.rs @@ -13,3 +13,13 @@ impl EvaluationResult { matches!(self, Self::Passed) } } + +impl From<&str> for EvaluationResult { + fn from(value: &str) -> Self { + if value.eq_ignore_ascii_case("failed") { + EvaluationResult::Failed + } else { + EvaluationResult::Passed + } + } +} diff --git a/src/domain/scanresult/scan_result.rs b/src/domain/scanresult/scan_result.rs index e2b2df3..2221061 100644 --- a/src/domain/scanresult/scan_result.rs +++ b/src/domain/scanresult/scan_result.rs @@ -27,6 +27,7 @@ pub struct ScanResult { policies: HashMap>, policy_bundles: HashMap>, accepted_risks: HashMap>, + global_evaluation: EvaluationResult, } impl ScanResult { @@ -41,6 +42,7 @@ impl ScanResult { architecture: Architecture, labels: HashMap, created_at: DateTime, + global_evaluation: EvaluationResult, ) -> Self { Self { scan_type, @@ -60,6 +62,7 @@ impl ScanResult { policies: HashMap::new(), policy_bundles: HashMap::new(), accepted_risks: HashMap::new(), + global_evaluation, } } @@ -242,15 +245,7 @@ impl ScanResult { } pub fn evaluation_result(&self) -> EvaluationResult { - if self - .policies() - .iter() - .all(|p| p.evaluation_result().is_passed()) - { - EvaluationResult::Passed - } else { - EvaluationResult::Failed - } + self.global_evaluation } } @@ -277,6 +272,7 @@ mod tests { Architecture::Amd64, HashMap::new(), Utc::now(), + EvaluationResult::Failed, ) } @@ -505,7 +501,18 @@ mod tests { #[test] fn evaluation_result_passed() { - let mut scan_result = create_scan_result(); + let mut scan_result = ScanResult::new( + ScanType::Docker, + "alpine:latest".to_string(), + "sha256:12345".to_string(), + Some("sha256:67890".to_string()), + OperatingSystem::new(Family::Linux, "alpine:3.18".to_string()), + 123456, + Architecture::Amd64, + HashMap::new(), + Utc::now(), + EvaluationResult::Passed, + ); let now = Utc::now(); let policy = scan_result.add_policy("policy-1".to_string(), "My Policy".to_string(), now, now); @@ -758,7 +765,11 @@ mod tests { assert_eq!(bundle.evaluation_result(), EvaluationResult::Passed); assert_eq!(policy.evaluation_result(), EvaluationResult::Passed); - assert_eq!(scan_result.evaluation_result(), EvaluationResult::Passed); + assert_eq!( + scan_result.evaluation_result(), + EvaluationResult::Failed, + "Global evaluation should remain Failed" + ); let failed_rule = bundle.add_rule( "rule-failed".to_string(), @@ -780,6 +791,10 @@ mod tests { assert_eq!(bundle.evaluation_result(), EvaluationResult::Failed); assert_eq!(policy.evaluation_result(), EvaluationResult::Failed); - assert_eq!(scan_result.evaluation_result(), EvaluationResult::Failed); + assert_eq!( + scan_result.evaluation_result(), + EvaluationResult::Failed, + "Global evaluation should remain Failed" + ); } } diff --git a/src/infra/sysdig_image_scanner_json_scan_result_v1.rs b/src/infra/sysdig_image_scanner_json_scan_result_v1.rs index 6d576d2..bd96f9f 100644 --- a/src/infra/sysdig_image_scanner_json_scan_result_v1.rs +++ b/src/infra/sysdig_image_scanner_json_scan_result_v1.rs @@ -7,7 +7,6 @@ use std::collections::HashMap; use crate::domain::scanresult::{ accepted_risk_reason::AcceptedRiskReason, architecture::Architecture, - evaluation_result::EvaluationResult, operating_system::{Family, OperatingSystem}, package_type::PackageType, scan_result::ScanResult, @@ -17,7 +16,7 @@ use crate::domain::scanresult::{ impl From for ScanResult { fn from(report: JsonScanResultV1) -> Self { - let mut scan_result = ScanResult::from(&report.result.metadata); + let mut scan_result = ScanResult::from(&report.result); add_layers(&report.result, &mut scan_result); add_risk_accepts(&report.result, &mut scan_result); @@ -145,11 +144,7 @@ fn add_policies(result: &JsonResult, scan_result: &mut ScanResult) { let rule = policy_bundle.add_rule( json_rule.rule_id.clone(), json_rule.description.clone(), - if json_rule.evaluation_result.eq_ignore_ascii_case("failed") { - EvaluationResult::Failed - } else { - EvaluationResult::Passed - }, + json_rule.evaluation_result.as_str().into(), ); for json_failure in json_rule.failures.as_deref().unwrap_or_default() { @@ -188,8 +183,9 @@ fn failure_message_for(result: &JsonResult, package_ref: &str, vulnerability_ref } } -impl From<&JsonMetadata> for ScanResult { - fn from(metadata: &JsonMetadata) -> Self { +impl From<&JsonResult> for ScanResult { + fn from(result: &JsonResult) -> Self { + let metadata = &result.metadata; ScanResult::new( ScanType::Docker, metadata.pull_string.clone(), @@ -200,6 +196,7 @@ impl From<&JsonMetadata> for ScanResult { arch_from_str(&metadata.architecture), metadata.labels.clone(), metadata.created_at, + result.policies.global_evaluation.as_str().into(), ) } } diff --git a/tests/general.rs b/tests/general.rs index 10a2bf8..a5fd65b 100644 --- a/tests/general.rs +++ b/tests/general.rs @@ -5,6 +5,7 @@ use rstest::{fixture, rstest}; use serde_json::json; use std::collections::HashMap; use sysdig_lsp::domain::scanresult::architecture::Architecture; +use sysdig_lsp::domain::scanresult::evaluation_result::EvaluationResult; use sysdig_lsp::domain::scanresult::operating_system::{Family, OperatingSystem}; use sysdig_lsp::domain::scanresult::scan_result::ScanResult; use sysdig_lsp::domain::scanresult::scan_type::ScanType; @@ -120,6 +121,7 @@ fn scan_result() -> ScanResult { Architecture::Amd64, HashMap::new(), chrono::Utc::now(), + EvaluationResult::Passed, ); let layer = result.add_layer( From 5b21e4ccb9717034a3b92ce7d8e3d3e363ef7345 Mon Sep 17 00:00:00 2001 From: Fede Barcelona Date: Tue, 28 Oct 2025 09:20:13 +0100 Subject: [PATCH 2/2] chore: release 0.7.2 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7478772..7105123 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2035,7 +2035,7 @@ dependencies = [ [[package]] name = "sysdig-lsp" -version = "0.7.1" +version = "0.7.2" dependencies = [ "async-trait", "bollard", diff --git a/Cargo.toml b/Cargo.toml index a7eaedd..6cfc324 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sysdig-lsp" -version = "0.7.1" +version = "0.7.2" edition = "2024" authors = [ "Sysdig Inc." ] readme = "README.md"