Skip to content

Commit c434775

Browse files
smtan-glafdesk
andauthored
fix(k8s)!: support k8s multi container (#7444)
Co-authored-by: afdesk <work@afdesk.com>
1 parent 7a4f4d8 commit c434775

File tree

2 files changed

+165
-36
lines changed

2 files changed

+165
-36
lines changed

pkg/k8s/report/report.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ type Resource struct {
5757
Namespace string `json:",omitempty"`
5858
Kind string
5959
Name string
60-
Metadata types.Metadata `json:",omitempty"`
61-
Results types.Results `json:",omitempty"`
62-
Error string `json:",omitempty"`
60+
Metadata []types.Metadata `json:",omitempty"`
61+
Results types.Results `json:",omitempty"`
62+
Error string `json:",omitempty"`
6363

6464
// original report
6565
Report types.Report `json:"-"`
@@ -99,11 +99,15 @@ func (r Report) consolidate() ConsolidatedReport {
9999
key := v.fullname()
100100

101101
if res, ok := index[key]; ok {
102+
// Combine metadata
103+
metadata := lo.UniqBy(append(res.Metadata, v.Metadata...), func(x types.Metadata) string {
104+
return x.ImageID
105+
})
102106
index[key] = Resource{
103107
Namespace: res.Namespace,
104108
Kind: res.Kind,
105109
Name: res.Name,
106-
Metadata: res.Metadata,
110+
Metadata: metadata,
107111
Results: append(res.Results, v.Results...),
108112
Error: res.Error,
109113
}
@@ -214,7 +218,7 @@ func infraResource(misConfig Resource) bool {
214218
func CreateResource(artifact *artifacts.Artifact, report types.Report, err error) Resource {
215219
r := createK8sResource(artifact, report.Results)
216220

217-
r.Metadata = report.Metadata
221+
r.Metadata = []types.Metadata{report.Metadata}
218222
r.Report = report
219223
// if there was any error during the scan
220224
if err != nil {
@@ -244,7 +248,7 @@ func createK8sResource(artifact *artifacts.Artifact, scanResults types.Results)
244248
Namespace: artifact.Namespace,
245249
Kind: artifact.Kind,
246250
Name: artifact.Name,
247-
Metadata: types.Metadata{},
251+
Metadata: []types.Metadata{},
248252
Results: results,
249253
Report: types.Report{
250254
Results: results,

pkg/k8s/report/report_test.go

Lines changed: 155 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@ var (
1414
Namespace: "default",
1515
Kind: "Deploy",
1616
Name: "orion",
17-
Metadata: types.Metadata{
18-
RepoTags: []string{
19-
"alpine:3.14",
20-
},
21-
RepoDigests: []string{
22-
"alpine:3.14@sha256:8fe1727132b2506c17ba0e1f6a6ed8a016bb1f5735e43b2738cd3fd1979b6260",
17+
Metadata: []types.Metadata{
18+
{
19+
ImageID: "123",
20+
RepoTags: []string{
21+
"alpine:3.14",
22+
},
23+
RepoDigests: []string{
24+
"alpine:3.14@sha256:8fe1727132b2506c17ba0e1f6a6ed8a016bb1f5735e43b2738cd3fd1979b6260",
25+
},
2326
},
2427
},
2528
Results: types.Results{
@@ -69,12 +72,15 @@ var (
6972
Namespace: "default",
7073
Kind: "Deploy",
7174
Name: "orion",
72-
Metadata: types.Metadata{
73-
RepoTags: []string{
74-
"alpine:3.14",
75-
},
76-
RepoDigests: []string{
77-
"alpine:3.14@sha256:8fe1727132b2506c17ba0e1f6a6ed8a016bb1f5735e43b2738cd3fd1979b6260",
75+
Metadata: []types.Metadata{
76+
{
77+
ImageID: "123",
78+
RepoTags: []string{
79+
"alpine:3.14",
80+
},
81+
RepoDigests: []string{
82+
"alpine:3.14@sha256:8fe1727132b2506c17ba0e1f6a6ed8a016bb1f5735e43b2738cd3fd1979b6260",
83+
},
7884
},
7985
},
8086
Results: types.Results{
@@ -113,16 +119,117 @@ var (
113119
},
114120
}
115121

122+
image1WithVulns = Resource{
123+
Namespace: "default",
124+
Kind: "Pod",
125+
Name: "multi-image-pod",
126+
Metadata: []types.Metadata{
127+
{
128+
ImageID: "image1",
129+
RepoTags: []string{
130+
"alpine:3.14",
131+
},
132+
RepoDigests: []string{
133+
"alpine:3.14@sha256:8fe1727132b2506c17ba0e1f6a6ed8a016bb1f5735e43b2738cd3fd1979b6260",
134+
},
135+
},
136+
},
137+
Results: types.Results{
138+
{
139+
Vulnerabilities: []types.DetectedVulnerability{
140+
{
141+
VulnerabilityID: "CVE-2022-1111",
142+
Vulnerability: dbTypes.Vulnerability{Severity: "LOW"},
143+
},
144+
},
145+
},
146+
},
147+
}
148+
149+
image2WithVulns = Resource{
150+
Namespace: "default",
151+
Kind: "Pod",
152+
Name: "multi-image-pod",
153+
Metadata: []types.Metadata{
154+
{
155+
ImageID: "image2",
156+
RepoTags: []string{
157+
"alpine:3.17.3",
158+
},
159+
RepoDigests: []string{
160+
"alpine@sha256:124c7d2707904eea7431fffe91522a01e5a861a624ee31d03372cc1d138a3126",
161+
},
162+
},
163+
},
164+
Results: types.Results{
165+
{
166+
Vulnerabilities: []types.DetectedVulnerability{
167+
{
168+
VulnerabilityID: "CVE-2022-2222",
169+
Vulnerability: dbTypes.Vulnerability{Severity: "MEDIUM"},
170+
},
171+
},
172+
},
173+
},
174+
}
175+
176+
multiImagePodWithVulns = Resource{
177+
Namespace: "default",
178+
Kind: "Pod",
179+
Name: "multi-image-pod",
180+
Metadata: []types.Metadata{
181+
{
182+
ImageID: "image1",
183+
RepoTags: []string{
184+
"alpine:3.14",
185+
},
186+
RepoDigests: []string{
187+
"alpine:3.14@sha256:8fe1727132b2506c17ba0e1f6a6ed8a016bb1f5735e43b2738cd3fd1979b6260",
188+
},
189+
},
190+
{
191+
ImageID: "image2",
192+
RepoTags: []string{
193+
"alpine:3.17.3",
194+
},
195+
RepoDigests: []string{
196+
"alpine@sha256:124c7d2707904eea7431fffe91522a01e5a861a624ee31d03372cc1d138a3126",
197+
},
198+
},
199+
},
200+
Results: types.Results{
201+
{
202+
Vulnerabilities: []types.DetectedVulnerability{
203+
{
204+
VulnerabilityID: "CVE-2022-1111",
205+
Vulnerability: dbTypes.Vulnerability{Severity: "LOW"},
206+
},
207+
},
208+
},
209+
{
210+
Vulnerabilities: []types.DetectedVulnerability{
211+
{
212+
VulnerabilityID: "CVE-2022-2222",
213+
Vulnerability: dbTypes.Vulnerability{Severity: "MEDIUM"},
214+
},
215+
},
216+
},
217+
},
218+
}
219+
116220
deployOrionWithBothVulnsAndMisconfigs = Resource{
117221
Namespace: "default",
118222
Kind: "Deploy",
119223
Name: "orion",
120-
Metadata: types.Metadata{
121-
RepoTags: []string{
122-
"alpine:3.14",
123-
},
124-
RepoDigests: []string{
125-
"alpine:3.14@sha256:8fe1727132b2506c17ba0e1f6a6ed8a016bb1f5735e43b2738cd3fd1979b6260",
224+
Metadata: []types.Metadata{
225+
{
226+
ImageID: "123",
227+
RepoTags: []string{
228+
"alpine:3.14",
229+
},
230+
RepoDigests: []string{
231+
"alpine:3.14@sha256:8fe1727132b2506c17ba0e1f6a6ed8a016bb1f5735e43b2738cd3fd1979b6260",
232+
},
126233
},
127234
},
128235
Results: types.Results{
@@ -204,12 +311,15 @@ var (
204311
Namespace: "default",
205312
Kind: "Cronjob",
206313
Name: "hello",
207-
Metadata: types.Metadata{
208-
RepoTags: []string{
209-
"alpine:3.14",
210-
},
211-
RepoDigests: []string{
212-
"alpine:3.14@sha256:8fe1727132b2506c17ba0e1f6a6ed8a016bb1f5735e43b2738cd3fd1979b6260",
314+
Metadata: []types.Metadata{
315+
{
316+
ImageID: "123",
317+
RepoTags: []string{
318+
"alpine:3.14",
319+
},
320+
RepoDigests: []string{
321+
"alpine:3.14@sha256:8fe1727132b2506c17ba0e1f6a6ed8a016bb1f5735e43b2738cd3fd1979b6260",
322+
},
213323
},
214324
},
215325
Results: types.Results{
@@ -221,12 +331,15 @@ var (
221331
Namespace: "default",
222332
Kind: "Pod",
223333
Name: "prometheus",
224-
Metadata: types.Metadata{
225-
RepoTags: []string{
226-
"alpine:3.14",
227-
},
228-
RepoDigests: []string{
229-
"alpine:3.14@sha256:8fe1727132b2506c17ba0e1f6a6ed8a016bb1f5735e43b2738cd3fd1979b6260",
334+
Metadata: []types.Metadata{
335+
{
336+
ImageID: "123",
337+
RepoTags: []string{
338+
"alpine:3.14",
339+
},
340+
RepoDigests: []string{
341+
"alpine:3.14@sha256:8fe1727132b2506c17ba0e1f6a6ed8a016bb1f5735e43b2738cd3fd1979b6260",
342+
},
230343
},
231344
},
232345
Results: types.Results{
@@ -358,6 +471,18 @@ func TestReport_consolidate(t *testing.T) {
358471
"default/cronjob/hello": cronjobHelloWithVulns,
359472
},
360473
},
474+
{
475+
name: "report with multi image pod containing vulnerabilities",
476+
report: Report{
477+
Resources: []Resource{
478+
image1WithVulns,
479+
image2WithVulns,
480+
},
481+
},
482+
expectedFindings: map[string]Resource{
483+
"default/pod/multi-image-pod": multiImagePodWithVulns,
484+
},
485+
},
361486
}
362487

363488
for _, tt := range tests {

0 commit comments

Comments
 (0)