Skip to content

Commit 98692cb

Browse files
committed
feat: add conversion from layer to markdown
1 parent d9a9cba commit 98692cb

File tree

4 files changed

+117
-4
lines changed

4 files changed

+117
-4
lines changed

src/app/markdown/markdown_fixable_package_table.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
use std::fmt::{Display, Formatter};
1+
use std::{
2+
fmt::{Display, Formatter},
3+
sync::Arc,
4+
};
25

36
use markdown_table::{Heading, HeadingAlignment, MarkdownTable};
47

5-
use crate::domain::scanresult::{scan_result::ScanResult, severity::Severity};
8+
use crate::domain::scanresult::{layer::Layer, scan_result::ScanResult, severity::Severity};
69

710
#[derive(Clone, Debug, Default)]
811
pub struct FixablePackage {
@@ -67,6 +70,47 @@ impl From<&ScanResult> for FixablePackageTable {
6770
}
6871
}
6972

73+
impl From<&Arc<Layer>> for FixablePackageTable {
74+
fn from(value: &Arc<Layer>) -> Self {
75+
FixablePackageTable(
76+
value
77+
.packages()
78+
.into_iter()
79+
.filter(|p| p.vulnerabilities().iter().any(|v| v.fixable()))
80+
.map(|p| {
81+
let mut vulns = FixablePackageVulnerabilities::default();
82+
let mut exploits = 0;
83+
for v in p.vulnerabilities() {
84+
if v.exploitable() {
85+
exploits += 1;
86+
}
87+
match v.severity() {
88+
Severity::Critical => vulns.critical += 1,
89+
Severity::High => vulns.high += 1,
90+
Severity::Medium => vulns.medium += 1,
91+
Severity::Low => vulns.low += 1,
92+
Severity::Negligible => vulns.negligible += 1,
93+
Severity::Unknown => {}
94+
}
95+
}
96+
97+
FixablePackage {
98+
name: p.name().to_string(),
99+
package_type: p.package_type().to_string(),
100+
version: p.version().to_string(),
101+
suggested_fix: p
102+
.vulnerabilities()
103+
.iter()
104+
.find_map(|v| v.fix_version().map(|s| s.to_string())),
105+
vulnerabilities: vulns,
106+
exploits,
107+
}
108+
})
109+
.collect(),
110+
)
111+
}
112+
}
113+
70114
impl Display for FixablePackageTable {
71115
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
72116
if self.0.is_empty() {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use std::{
2+
fmt::{Display, Formatter},
3+
sync::Arc,
4+
};
5+
6+
use crate::domain::scanresult::layer::Layer;
7+
8+
use super::{
9+
markdown_fixable_package_table::FixablePackageTable,
10+
markdown_vulnerability_evaluated_table::VulnerabilityEvaluatedTable,
11+
};
12+
13+
pub struct MarkdownLayerData {
14+
pub fixable_packages: FixablePackageTable,
15+
pub vulnerabilities: VulnerabilityEvaluatedTable,
16+
}
17+
18+
impl From<Arc<Layer>> for MarkdownLayerData {
19+
fn from(value: Arc<Layer>) -> Self {
20+
Self {
21+
fixable_packages: FixablePackageTable::from(&value),
22+
vulnerabilities: VulnerabilityEvaluatedTable::from(&value),
23+
}
24+
}
25+
}
26+
27+
impl Display for MarkdownLayerData {
28+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
29+
let fixable_packages_section = self.fixable_packages.to_string();
30+
let vulnerability_detail_section = self.vulnerabilities.to_string();
31+
32+
write!(
33+
f,
34+
"## Sysdig Scan Result for Layer\n{}\n{}",
35+
fixable_packages_section, vulnerability_detail_section
36+
)
37+
}
38+
}

src/app/markdown/markdown_vulnerability_evaluated_table.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
use std::fmt::{Display, Formatter};
1+
use std::{
2+
fmt::{Display, Formatter},
3+
sync::Arc,
4+
};
25

36
use itertools::Itertools;
47
use markdown_table::{Heading, HeadingAlignment, MarkdownTable};
58

6-
use crate::domain::scanresult::scan_result::ScanResult;
9+
use crate::domain::scanresult::{layer::Layer, scan_result::ScanResult};
710

811
#[derive(Clone, Debug, Default)]
912
pub struct VulnerabilityEvaluated {
@@ -45,6 +48,33 @@ impl From<&ScanResult> for VulnerabilityEvaluatedTable {
4548
)
4649
}
4750
}
51+
impl From<&Arc<Layer>> for VulnerabilityEvaluatedTable {
52+
fn from(value: &Arc<Layer>) -> Self {
53+
VulnerabilityEvaluatedTable(
54+
value
55+
.vulnerabilities()
56+
.iter()
57+
.sorted_by_key(|v| v.cve())
58+
.sorted_by(|a, b| {
59+
b.found_in_packages()
60+
.len()
61+
.cmp(&a.found_in_packages().len())
62+
})
63+
.sorted_by(|a, b| b.fixable().cmp(&a.fixable()))
64+
.sorted_by(|a, b| b.exploitable().cmp(&a.exploitable()))
65+
.sorted_by_key(|v| v.severity())
66+
.map(|v| VulnerabilityEvaluated {
67+
cve: v.cve().to_string(),
68+
severity: v.severity().to_string(),
69+
packages_found: v.found_in_packages().len() as u32,
70+
fixable: v.fixable(),
71+
exploitable: v.exploitable(),
72+
accepted_risk: !v.accepted_risks().is_empty(),
73+
})
74+
.collect(),
75+
)
76+
}
77+
}
4878

4979
impl Display for VulnerabilityEvaluatedTable {
5080
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {

src/app/markdown/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod markdown_data;
22
mod markdown_fixable_package_table;
3+
mod markdown_layer_data;
34
mod markdown_policy_evaluated_table;
45
mod markdown_summary;
56
mod markdown_summary_table;

0 commit comments

Comments
 (0)