feat(CVE): add CVE severity counters to returned images and CVE list calls (#2131)
For CLI output is similar to: CRITICAL 0, HIGH 1, MEDIUM 1, LOW 0, UNKNOWN 0, TOTAL 2 ID SEVERITY TITLE CVE-2023-0464 HIGH openssl: Denial of service by excessive resou... CVE-2023-0465 MEDIUM openssl: Invalid certificate policies in leaf... Signed-off-by: Andrei Aaron <aaaron@luxoft.com>
This commit is contained in:
parent
dbb1c3519f
commit
18aa975ae2
@ -141,7 +141,8 @@ func TestSearchCVECmd(t *testing.T) {
|
||||
err := cmd.Execute()
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "ID SEVERITY TITLE dummyCVEID HIGH Title of that CVE")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "CRITICAL 0, HIGH 1, MEDIUM 0, LOW 0, UNKNOWN 0, TOTAL 1 "+
|
||||
"ID SEVERITY TITLE dummyCVEID HIGH Title of that CVE")
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
@ -207,7 +208,8 @@ func TestSearchCVECmd(t *testing.T) {
|
||||
err := cveCmd.Execute()
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "ID SEVERITY TITLE dummyCVEID HIGH Title of that CVE")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "CRITICAL 0, HIGH 1, MEDIUM 0, LOW 0, UNKNOWN 0, TOTAL 1 "+
|
||||
"ID SEVERITY TITLE dummyCVEID HIGH Title of that CVE")
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
@ -225,7 +227,9 @@ func TestSearchCVECmd(t *testing.T) {
|
||||
So(buff.String(), ShouldEqual, `{"Tag":"dummyImageName:tag","CVEList":`+
|
||||
`[{"Id":"dummyCVEID","Severity":"HIGH","Title":"Title of that CVE",`+
|
||||
`"Description":"Description of the CVE","PackageList":[{"Name":"packagename",`+
|
||||
`"InstalledVersion":"installedver","FixedVersion":"fixedver"}]}]}`+"\n")
|
||||
`"InstalledVersion":"installedver","FixedVersion":"fixedver"}]}],"Summary":`+
|
||||
`{"maxSeverity":"HIGH","unknownCount":0,"lowCount":0,"mediumCount":0,"highCount":1,`+
|
||||
`"criticalCount":0,"count":1}}`+"\n")
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
@ -243,7 +247,8 @@ func TestSearchCVECmd(t *testing.T) {
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
So(strings.TrimSpace(str), ShouldEqual, `--- tag: dummyImageName:tag cvelist: - id: dummyCVEID`+
|
||||
` severity: HIGH title: Title of that CVE description: Description of the CVE packagelist: `+
|
||||
`- name: packagename installedversion: installedver fixedversion: fixedver`)
|
||||
`- name: packagename installedversion: installedver fixedversion: fixedver `+
|
||||
`summary: maxseverity: HIGH unknowncount: 0 lowcount: 0 mediumcount: 0 highcount: 1 criticalcount: 0 count: 1`)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
Convey("Test CVE by image name - invalid format", t, func() {
|
||||
@ -508,6 +513,7 @@ func TestCVECommandGQL(t *testing.T) {
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
actual := strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "CRITICAL 0, HIGH 1, MEDIUM 0, LOW 0, UNKNOWN 0, TOTAL 1")
|
||||
So(actual, ShouldContainSubstring, "dummyCVEID HIGH Title of that CVE")
|
||||
})
|
||||
|
||||
|
@ -634,7 +634,7 @@ func TestCVESort(t *testing.T) {
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
actual := strings.TrimSpace(str)
|
||||
So(actual, ShouldResemble,
|
||||
"ID SEVERITY TITLE "+
|
||||
"CRITICAL 1, HIGH 1, MEDIUM 2, LOW 1, UNKNOWN 0, TOTAL 5 ID SEVERITY TITLE "+
|
||||
"CVE-2023-3446 CRITICAL Excessive time spent checking DH keys and par... "+
|
||||
"CVE-2023-2975 HIGH AES-SIV cipher implementation contains a bug ... "+
|
||||
"CVE-2023-2650 MEDIUM Possible DoS translating ASN.1 object identif... "+
|
||||
@ -652,7 +652,7 @@ func TestCVESort(t *testing.T) {
|
||||
str = space.ReplaceAllString(buff.String(), " ")
|
||||
actual = strings.TrimSpace(str)
|
||||
So(actual, ShouldResemble,
|
||||
"ID SEVERITY TITLE "+
|
||||
"CRITICAL 1, HIGH 1, MEDIUM 2, LOW 1, UNKNOWN 0, TOTAL 5 ID SEVERITY TITLE "+
|
||||
"CVE-2023-1255 LOW Input buffer over-read in AES-XTS implementat... "+
|
||||
"CVE-2023-2650 MEDIUM Possible DoS translating ASN.1 object identif... "+
|
||||
"CVE-2023-2975 HIGH AES-SIV cipher implementation contains a bug ... "+
|
||||
@ -670,7 +670,7 @@ func TestCVESort(t *testing.T) {
|
||||
str = space.ReplaceAllString(buff.String(), " ")
|
||||
actual = strings.TrimSpace(str)
|
||||
So(actual, ShouldResemble,
|
||||
"ID SEVERITY TITLE "+
|
||||
"CRITICAL 1, HIGH 1, MEDIUM 2, LOW 1, UNKNOWN 0, TOTAL 5 ID SEVERITY TITLE "+
|
||||
"CVE-2023-3817 MEDIUM Excessive time spent checking DH q parameter ... "+
|
||||
"CVE-2023-3446 CRITICAL Excessive time spent checking DH keys and par... "+
|
||||
"CVE-2023-2975 HIGH AES-SIV cipher implementation contains a bug ... "+
|
||||
|
@ -384,11 +384,13 @@ func TestOutputFormat(t *testing.T) {
|
||||
`"lastUpdated":"0001-01-01T00:00:00Z","size":"123445","platform":{"os":"os","arch":"arch",`+
|
||||
`"variant":""},"isSigned":false,"downloadCount":0,`+
|
||||
`"layers":[{"size":"","digest":"sha256:c122a146f0d02349be211bb95cc2530f4a5793f96edbdfa00860f741e5d8c0e6",`+
|
||||
`"score":0}],"history":null,"vulnerabilities":{"maxSeverity":"","count":0},`+
|
||||
`"score":0}],"history":null,"vulnerabilities":{"maxSeverity":"","unknownCount":0,"lowCount":0,`+
|
||||
`"mediumCount":0,"highCount":0,"criticalCount":0,"count":0},`+
|
||||
`"referrers":null,"artifactType":"","signatureInfo":null}],"size":"123445",`+
|
||||
`"downloadCount":0,"lastUpdated":"0001-01-01T00:00:00Z","description":"","isSigned":false,"licenses":"",`+
|
||||
`"labels":"","title":"","source":"","documentation":"","authors":"","vendor":"",`+
|
||||
`"vulnerabilities":{"maxSeverity":"","count":0},"referrers":null,"signatureInfo":null}`+"\n")
|
||||
`"vulnerabilities":{"maxSeverity":"","unknownCount":0,"lowCount":0,"mediumCount":0,"highCount":0,`+
|
||||
`"criticalCount":0,"count":0},"referrers":null,"signatureInfo":null}`+"\n")
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
@ -415,10 +417,13 @@ func TestOutputFormat(t *testing.T) {
|
||||
`lastupdated: 0001-01-01T00:00:00Z size: "123445" platform: os: os arch: arch variant: "" `+
|
||||
`issigned: false downloadcount: 0 layers: - size: "" `+
|
||||
`digest: sha256:c122a146f0d02349be211bb95cc2530f4a5793f96edbdfa00860f741e5d8c0e6 score: 0 `+
|
||||
`history: [] vulnerabilities: maxseverity: "" count: 0 referrers: [] artifacttype: "" `+
|
||||
`history: [] vulnerabilities: maxseverity: "" `+
|
||||
`unknowncount: 0 lowcount: 0 mediumcount: 0 highcount: 0 criticalcount: 0 count: 0 `+
|
||||
`referrers: [] artifacttype: "" `+
|
||||
`signatureinfo: [] size: "123445" downloadcount: 0 `+
|
||||
`lastupdated: 0001-01-01T00:00:00Z description: "" issigned: false licenses: "" labels: "" `+
|
||||
`title: "" source: "" documentation: "" authors: "" vendor: "" vulnerabilities: maxseverity: "" `+
|
||||
`unknowncount: 0 lowcount: 0 mediumcount: 0 highcount: 0 criticalcount: 0 `+
|
||||
`count: 0 referrers: [] signatureinfo: []`,
|
||||
)
|
||||
So(err, ShouldBeNil)
|
||||
@ -449,11 +454,13 @@ func TestOutputFormat(t *testing.T) {
|
||||
`lastupdated: 0001-01-01T00:00:00Z size: "123445" platform: os: os arch: arch variant: "" `+
|
||||
`issigned: false downloadcount: 0 layers: - size: "" `+
|
||||
`digest: sha256:c122a146f0d02349be211bb95cc2530f4a5793f96edbdfa00860f741e5d8c0e6 score: 0 `+
|
||||
`history: [] vulnerabilities: maxseverity: "" count: 0 referrers: [] artifacttype: "" `+
|
||||
`history: [] vulnerabilities: maxseverity: "" unknowncount: 0 lowcount: 0 mediumcount: 0 `+
|
||||
`highcount: 0 criticalcount: 0 count: 0 referrers: [] artifacttype: "" `+
|
||||
`signatureinfo: [] size: "123445" downloadcount: 0 `+
|
||||
`lastupdated: 0001-01-01T00:00:00Z description: "" issigned: false licenses: "" labels: "" `+
|
||||
`title: "" source: "" documentation: "" authors: "" vendor: "" vulnerabilities: maxseverity: `+
|
||||
`"" count: 0 referrers: [] signatureinfo: []`,
|
||||
`title: "" source: "" documentation: "" authors: "" vendor: "" vulnerabilities: maxseverity: "" `+
|
||||
`unknowncount: 0 lowcount: 0 mediumcount: 0 highcount: 0 criticalcount: 0 `+
|
||||
`count: 0 referrers: [] signatureinfo: []`,
|
||||
)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
@ -783,6 +790,7 @@ func TestImagesCommandGQL(t *testing.T) {
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
actual := strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "CRITICAL 0, HIGH 1, MEDIUM 0, LOW 0, UNKNOWN 0, TOTAL 1")
|
||||
So(actual, ShouldContainSubstring, "dummyCVEID HIGH Title of that CVE")
|
||||
})
|
||||
|
||||
@ -1342,6 +1350,15 @@ func (service mockService) getCveByImageGQL(ctx context.Context, config SearchCo
|
||||
},
|
||||
},
|
||||
},
|
||||
Summary: common.ImageVulnerabilitySummary{
|
||||
Count: 1,
|
||||
UnknownCount: 0,
|
||||
LowCount: 0,
|
||||
MediumCount: 0,
|
||||
HighCount: 1,
|
||||
CriticalCount: 0,
|
||||
MaxSeverity: "HIGH",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -379,11 +379,13 @@ func TestOutputFormatGQL(t *testing.T) {
|
||||
`"lastUpdated":"2023-01-01T12:00:00Z","size":"528","platform":{"os":"linux","arch":"amd64",` +
|
||||
`"variant":""},"isSigned":false,"downloadCount":0,"layers":[{"size":"15","digest":` +
|
||||
`"sha256:b8781e8844f5b7bf6f2f8fa343de18ec471c3b278027355bc34c120585ff04f6","score":0}],` +
|
||||
`"history":null,"vulnerabilities":{"maxSeverity":"","count":0},` +
|
||||
`"history":null,"vulnerabilities":{"maxSeverity":"","unknownCount":0,"lowCount":0,"mediumCount":0,` +
|
||||
`"highCount":0,"criticalCount":0,"count":0},` +
|
||||
`"referrers":null,"artifactType":"","signatureInfo":null}],` +
|
||||
`"size":"528","downloadCount":0,"lastUpdated":"2023-01-01T12:00:00Z","description":"","isSigned":false,` +
|
||||
`"licenses":"","labels":"","title":"","source":"","documentation":"","authors":"","vendor":"",` +
|
||||
`"vulnerabilities":{"maxSeverity":"","count":0},"referrers":null,"signatureInfo":null}` + "\n" +
|
||||
`"vulnerabilities":{"maxSeverity":"","unknownCount":0,"lowCount":0,"mediumCount":0,` +
|
||||
`"highCount":0,"criticalCount":0,"count":0},"referrers":null,"signatureInfo":null}` + "\n" +
|
||||
`{"repoName":"repo7","tag":"test:2.0",` +
|
||||
`"digest":"sha256:51e18f508fd7125b0831ff9a22ba74cd79f0b934e77661ff72cfb54896951a06",` +
|
||||
`"mediaType":"application/vnd.oci.image.manifest.v1+json",` +
|
||||
@ -392,11 +394,13 @@ func TestOutputFormatGQL(t *testing.T) {
|
||||
`"lastUpdated":"2023-01-01T12:00:00Z","size":"528","platform":{"os":"linux","arch":"amd64",` +
|
||||
`"variant":""},"isSigned":false,"downloadCount":0,"layers":[{"size":"15","digest":` +
|
||||
`"sha256:b8781e8844f5b7bf6f2f8fa343de18ec471c3b278027355bc34c120585ff04f6","score":0}],` +
|
||||
`"history":null,"vulnerabilities":{"maxSeverity":"","count":0},` +
|
||||
`"history":null,"vulnerabilities":{"maxSeverity":"","unknownCount":0,"lowCount":0,"mediumCount":0,` +
|
||||
`"highCount":0,"criticalCount":0,"count":0},` +
|
||||
`"referrers":null,"artifactType":"","signatureInfo":null}],` +
|
||||
`"size":"528","downloadCount":0,"lastUpdated":"2023-01-01T12:00:00Z","description":"","isSigned":false,` +
|
||||
`"licenses":"","labels":"","title":"","source":"","documentation":"","authors":"","vendor":"",` +
|
||||
`"vulnerabilities":{"maxSeverity":"","count":0},"referrers":null,"signatureInfo":null}` + "\n"
|
||||
`"vulnerabilities":{"maxSeverity":"","unknownCount":0,"lowCount":0,"mediumCount":0,` +
|
||||
`"highCount":0,"criticalCount":0,"count":0},"referrers":null,"signatureInfo":null}` + "\n"
|
||||
// Output is supposed to be in json lines format, keep all spaces as is for verification
|
||||
So(buff.String(), ShouldEqual, expectedStr)
|
||||
So(err, ShouldBeNil)
|
||||
@ -424,10 +428,13 @@ func TestOutputFormatGQL(t *testing.T) {
|
||||
`issigned: false downloadcount: 0 layers: - size: "15" ` +
|
||||
`digest: sha256:b8781e8844f5b7bf6f2f8fa343de18ec471c3b278027355bc34c120585ff04f6 score: 0 ` +
|
||||
`history: [] vulnerabilities: maxseverity: "" ` +
|
||||
`count: 0 referrers: [] artifacttype: "" signatureinfo: [] ` +
|
||||
`unknowncount: 0 lowcount: 0 mediumcount: 0 highcount: 0 criticalcount: 0 count: 0 ` +
|
||||
`referrers: [] artifacttype: "" signatureinfo: [] ` +
|
||||
`size: "528" downloadcount: 0 lastupdated: 2023-01-01T12:00:00Z description: "" ` +
|
||||
`issigned: false licenses: "" labels: "" title: "" source: "" documentation: "" ` +
|
||||
`authors: "" vendor: "" vulnerabilities: maxseverity: "" count: 0 referrers: [] signatureinfo: [] ` +
|
||||
`authors: "" vendor: "" vulnerabilities: maxseverity: "" ` +
|
||||
`unknowncount: 0 lowcount: 0 mediumcount: 0 highcount: 0 criticalcount: 0 count: 0 ` +
|
||||
`referrers: [] signatureinfo: [] ` +
|
||||
`--- reponame: repo7 tag: test:2.0 ` +
|
||||
`digest: sha256:51e18f508fd7125b0831ff9a22ba74cd79f0b934e77661ff72cfb54896951a06 ` +
|
||||
`mediatype: application/vnd.oci.image.manifest.v1+json manifests: - ` +
|
||||
@ -437,10 +444,13 @@ func TestOutputFormatGQL(t *testing.T) {
|
||||
`issigned: false downloadcount: 0 layers: - size: "15" ` +
|
||||
`digest: sha256:b8781e8844f5b7bf6f2f8fa343de18ec471c3b278027355bc34c120585ff04f6 score: 0 ` +
|
||||
`history: [] vulnerabilities: maxseverity: "" ` +
|
||||
`count: 0 referrers: [] artifacttype: "" signatureinfo: [] ` +
|
||||
`unknowncount: 0 lowcount: 0 mediumcount: 0 highcount: 0 criticalcount: 0 count: 0 ` +
|
||||
`referrers: [] artifacttype: "" signatureinfo: [] ` +
|
||||
`size: "528" downloadcount: 0 lastupdated: 2023-01-01T12:00:00Z description: "" ` +
|
||||
`issigned: false licenses: "" labels: "" title: "" source: "" documentation: "" ` +
|
||||
`authors: "" vendor: "" vulnerabilities: maxseverity: "" count: 0 referrers: [] signatureinfo: []`
|
||||
`authors: "" vendor: "" vulnerabilities: maxseverity: "" ` +
|
||||
`unknowncount: 0 lowcount: 0 mediumcount: 0 highcount: 0 criticalcount: 0 count: 0 ` +
|
||||
`referrers: [] signatureinfo: []`
|
||||
So(strings.TrimSpace(str), ShouldEqual, expectedStr)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
@ -467,11 +477,13 @@ func TestOutputFormatGQL(t *testing.T) {
|
||||
`issigned: false downloadcount: 0 layers: - size: "15" ` +
|
||||
`digest: sha256:b8781e8844f5b7bf6f2f8fa343de18ec471c3b278027355bc34c120585ff04f6 score: 0 ` +
|
||||
`history: [] vulnerabilities: maxseverity: "" ` +
|
||||
`count: 0 referrers: [] artifacttype: "" signatureinfo: [] ` +
|
||||
`unknowncount: 0 lowcount: 0 mediumcount: 0 highcount: 0 criticalcount: 0 count: 0 ` +
|
||||
`referrers: [] artifacttype: "" signatureinfo: [] ` +
|
||||
`size: "528" downloadcount: 0 lastupdated: 2023-01-01T12:00:00Z description: "" ` +
|
||||
`issigned: false licenses: "" labels: "" title: "" source: "" documentation: "" ` +
|
||||
`authors: "" vendor: "" vulnerabilities: maxseverity: "" ` +
|
||||
`count: 0 referrers: [] signatureinfo: [] ` +
|
||||
`unknowncount: 0 lowcount: 0 mediumcount: 0 highcount: 0 criticalcount: 0 count: 0 ` +
|
||||
`referrers: [] signatureinfo: [] ` +
|
||||
`--- reponame: repo7 tag: test:2.0 ` +
|
||||
`digest: sha256:51e18f508fd7125b0831ff9a22ba74cd79f0b934e77661ff72cfb54896951a06 ` +
|
||||
`mediatype: application/vnd.oci.image.manifest.v1+json manifests: - ` +
|
||||
@ -481,10 +493,13 @@ func TestOutputFormatGQL(t *testing.T) {
|
||||
`issigned: false downloadcount: 0 layers: - size: "15" ` +
|
||||
`digest: sha256:b8781e8844f5b7bf6f2f8fa343de18ec471c3b278027355bc34c120585ff04f6 score: 0 ` +
|
||||
`history: [] vulnerabilities: maxseverity: "" ` +
|
||||
`count: 0 referrers: [] artifacttype: "" signatureinfo: [] ` +
|
||||
`unknowncount: 0 lowcount: 0 mediumcount: 0 highcount: 0 criticalcount: 0 count: 0 ` +
|
||||
`referrers: [] artifacttype: "" signatureinfo: [] ` +
|
||||
`size: "528" downloadcount: 0 lastupdated: 2023-01-01T12:00:00Z description: "" ` +
|
||||
`issigned: false licenses: "" labels: "" title: "" source: "" documentation: "" ` +
|
||||
`authors: "" vendor: "" vulnerabilities: maxseverity: "" count: 0 referrers: [] signatureinfo: []`
|
||||
`authors: "" vendor: "" vulnerabilities: maxseverity: "" ` +
|
||||
`unknowncount: 0 lowcount: 0 mediumcount: 0 highcount: 0 criticalcount: 0 count: 0 ` +
|
||||
`referrers: [] signatureinfo: []`
|
||||
So(strings.TrimSpace(str), ShouldEqual, expectedStr)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
@ -245,6 +245,14 @@ func SearchCVEForImageGQL(config SearchConfig, image, searchedCveID string) erro
|
||||
var builder strings.Builder
|
||||
|
||||
if config.OutputFormat == defaultOutputFormat || config.OutputFormat == "" {
|
||||
imageCVESummary := cveList.Data.CVEListForImage.Summary
|
||||
|
||||
statsStr := fmt.Sprintf("CRITICAL %d, HIGH %d, MEDIUM %d, LOW %d, UNKNOWN %d, TOTAL %d\n\n",
|
||||
imageCVESummary.CriticalCount, imageCVESummary.HighCount, imageCVESummary.MediumCount,
|
||||
imageCVESummary.LowCount, imageCVESummary.UnknownCount, imageCVESummary.Count)
|
||||
|
||||
fmt.Fprint(config.ResultWriter, statsStr)
|
||||
|
||||
printCVETableHeader(&builder)
|
||||
fmt.Fprint(config.ResultWriter, builder.String())
|
||||
}
|
||||
|
@ -346,6 +346,15 @@ func TestSearchCVEForImageGQL(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
Summary: common.ImageVulnerabilitySummary{
|
||||
Count: 1,
|
||||
UnknownCount: 0,
|
||||
LowCount: 0,
|
||||
MediumCount: 0,
|
||||
HighCount: 1,
|
||||
CriticalCount: 0,
|
||||
MaxSeverity: "HIGH",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
@ -357,6 +366,7 @@ func TestSearchCVEForImageGQL(t *testing.T) {
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
actual := strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "CRITICAL 0, HIGH 1, MEDIUM 0, LOW 0, UNKNOWN 0, TOTAL 1")
|
||||
So(actual, ShouldContainSubstring, "dummyCVEID HIGH Title of that CVE")
|
||||
})
|
||||
|
||||
|
@ -305,10 +305,14 @@ func (service searchService) getCveByImageGQL(ctx context.Context, config Search
|
||||
query := fmt.Sprintf(`
|
||||
{
|
||||
CVEListForImage (image:"%s", searchedCVE:"%s", requestedPage: {sortBy: %s}) {
|
||||
Tag CVEList {
|
||||
Tag
|
||||
CVEList {
|
||||
Id Title Severity Description
|
||||
PackageList {Name InstalledVersion FixedVersion}
|
||||
}
|
||||
Summary {
|
||||
Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity
|
||||
}
|
||||
}
|
||||
}`, imageName, searchedCVE, Flag2SortCriteria(config.SortBy))
|
||||
result := &cveResult{}
|
||||
@ -743,8 +747,9 @@ type cve struct {
|
||||
|
||||
//nolint:tagliatelle // graphQL schema
|
||||
type cveListForImage struct {
|
||||
Tag string `json:"Tag"`
|
||||
CVEList []cve `json:"CVEList"`
|
||||
Tag string `json:"Tag"`
|
||||
CVEList []cve `json:"CVEList"`
|
||||
Summary common.ImageVulnerabilitySummary `json:"Summary"`
|
||||
}
|
||||
|
||||
//nolint:tagliatelle // graphQL schema
|
||||
|
@ -84,8 +84,13 @@ type Platform struct {
|
||||
}
|
||||
|
||||
type ImageVulnerabilitySummary struct {
|
||||
MaxSeverity string `json:"maxSeverity"`
|
||||
Count int `json:"count"`
|
||||
MaxSeverity string `json:"maxSeverity"`
|
||||
UnknownCount int `json:"unknownCount"`
|
||||
LowCount int `json:"lowCount"`
|
||||
MediumCount int `json:"mediumCount"`
|
||||
HighCount int `json:"highCount"`
|
||||
CriticalCount int `json:"criticalCount"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
type LayerSummary struct {
|
||||
|
@ -88,6 +88,11 @@ func TestCVEConvert(t *testing.T) {
|
||||
|
||||
So(imageSummary.Vulnerabilities, ShouldNotBeNil)
|
||||
So(*imageSummary.Vulnerabilities.Count, ShouldEqual, 0)
|
||||
So(*imageSummary.Vulnerabilities.UnknownCount, ShouldEqual, 0)
|
||||
So(*imageSummary.Vulnerabilities.LowCount, ShouldEqual, 0)
|
||||
So(*imageSummary.Vulnerabilities.MediumCount, ShouldEqual, 0)
|
||||
So(*imageSummary.Vulnerabilities.HighCount, ShouldEqual, 0)
|
||||
So(*imageSummary.Vulnerabilities.CriticalCount, ShouldEqual, 0)
|
||||
So(*imageSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "")
|
||||
So(graphql.GetErrors(ctx), ShouldBeNil)
|
||||
|
||||
@ -102,20 +107,35 @@ func TestCVEConvert(t *testing.T) {
|
||||
GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
return cvemodel.ImageCVESummary{
|
||||
Count: 1,
|
||||
MaxSeverity: "HIGH",
|
||||
Count: 30,
|
||||
UnknownCount: 1,
|
||||
LowCount: 2,
|
||||
MediumCount: 3,
|
||||
HighCount: 10,
|
||||
CriticalCount: 14,
|
||||
MaxSeverity: "HIGH",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
So(imageSummary.Vulnerabilities, ShouldNotBeNil)
|
||||
So(*imageSummary.Vulnerabilities.Count, ShouldEqual, 1)
|
||||
So(*imageSummary.Vulnerabilities.Count, ShouldEqual, 30)
|
||||
So(*imageSummary.Vulnerabilities.UnknownCount, ShouldEqual, 1)
|
||||
So(*imageSummary.Vulnerabilities.LowCount, ShouldEqual, 2)
|
||||
So(*imageSummary.Vulnerabilities.MediumCount, ShouldEqual, 3)
|
||||
So(*imageSummary.Vulnerabilities.HighCount, ShouldEqual, 10)
|
||||
So(*imageSummary.Vulnerabilities.CriticalCount, ShouldEqual, 14)
|
||||
So(*imageSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "HIGH")
|
||||
So(graphql.GetErrors(ctx), ShouldBeNil)
|
||||
So(len(imageSummary.Manifests), ShouldEqual, 1)
|
||||
So(imageSummary.Manifests[0].Vulnerabilities, ShouldNotBeNil)
|
||||
So(*imageSummary.Manifests[0].Vulnerabilities.Count, ShouldEqual, 1)
|
||||
So(*imageSummary.Manifests[0].Vulnerabilities.Count, ShouldEqual, 30)
|
||||
So(*imageSummary.Manifests[0].Vulnerabilities.UnknownCount, ShouldEqual, 1)
|
||||
So(*imageSummary.Manifests[0].Vulnerabilities.LowCount, ShouldEqual, 2)
|
||||
So(*imageSummary.Manifests[0].Vulnerabilities.MediumCount, ShouldEqual, 3)
|
||||
So(*imageSummary.Manifests[0].Vulnerabilities.HighCount, ShouldEqual, 10)
|
||||
So(*imageSummary.Manifests[0].Vulnerabilities.CriticalCount, ShouldEqual, 14)
|
||||
So(*imageSummary.Manifests[0].Vulnerabilities.MaxSeverity, ShouldEqual, "HIGH")
|
||||
|
||||
imageSummary.Vulnerabilities = nil
|
||||
@ -152,8 +172,13 @@ func TestCVEConvert(t *testing.T) {
|
||||
GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
return cvemodel.ImageCVESummary{
|
||||
Count: 1,
|
||||
MaxSeverity: "HIGH",
|
||||
Count: 30,
|
||||
UnknownCount: 1,
|
||||
LowCount: 2,
|
||||
MediumCount: 3,
|
||||
HighCount: 10,
|
||||
CriticalCount: 14,
|
||||
MaxSeverity: "HIGH",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
@ -182,15 +207,25 @@ func TestCVEConvert(t *testing.T) {
|
||||
GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
return cvemodel.ImageCVESummary{
|
||||
Count: 1,
|
||||
MaxSeverity: "HIGH",
|
||||
Count: 30,
|
||||
UnknownCount: 1,
|
||||
LowCount: 2,
|
||||
MediumCount: 3,
|
||||
HighCount: 10,
|
||||
CriticalCount: 14,
|
||||
MaxSeverity: "HIGH",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
So(repoSummary.NewestImage.Vulnerabilities, ShouldNotBeNil)
|
||||
So(*repoSummary.NewestImage.Vulnerabilities.Count, ShouldEqual, 1)
|
||||
So(*repoSummary.NewestImage.Vulnerabilities.Count, ShouldEqual, 30)
|
||||
So(*repoSummary.NewestImage.Vulnerabilities.UnknownCount, ShouldEqual, 1)
|
||||
So(*repoSummary.NewestImage.Vulnerabilities.LowCount, ShouldEqual, 2)
|
||||
So(*repoSummary.NewestImage.Vulnerabilities.MediumCount, ShouldEqual, 3)
|
||||
So(*repoSummary.NewestImage.Vulnerabilities.HighCount, ShouldEqual, 10)
|
||||
So(*repoSummary.NewestImage.Vulnerabilities.CriticalCount, ShouldEqual, 14)
|
||||
So(*repoSummary.NewestImage.Vulnerabilities.MaxSeverity, ShouldEqual, "HIGH")
|
||||
So(graphql.GetErrors(ctx), ShouldBeNil)
|
||||
})
|
||||
@ -251,15 +286,25 @@ func TestCVEConvert(t *testing.T) {
|
||||
GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
return cvemodel.ImageCVESummary{
|
||||
Count: 1,
|
||||
MaxSeverity: "HIGH",
|
||||
Count: 30,
|
||||
UnknownCount: 1,
|
||||
LowCount: 2,
|
||||
MediumCount: 3,
|
||||
HighCount: 10,
|
||||
CriticalCount: 14,
|
||||
MaxSeverity: "HIGH",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
So(manifestSummary.Vulnerabilities, ShouldNotBeNil)
|
||||
So(*manifestSummary.Vulnerabilities.Count, ShouldEqual, 1)
|
||||
So(*manifestSummary.Vulnerabilities.Count, ShouldEqual, 30)
|
||||
So(*manifestSummary.Vulnerabilities.UnknownCount, ShouldEqual, 1)
|
||||
So(*manifestSummary.Vulnerabilities.LowCount, ShouldEqual, 2)
|
||||
So(*manifestSummary.Vulnerabilities.MediumCount, ShouldEqual, 3)
|
||||
So(*manifestSummary.Vulnerabilities.HighCount, ShouldEqual, 10)
|
||||
So(*manifestSummary.Vulnerabilities.CriticalCount, ShouldEqual, 14)
|
||||
So(*manifestSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "HIGH")
|
||||
|
||||
manifestSummary.Vulnerabilities = nil
|
||||
|
@ -38,8 +38,13 @@ func updateImageSummaryVulnerabilities(
|
||||
imageCveSummary := cvemodel.ImageCVESummary{}
|
||||
|
||||
imageSummary.Vulnerabilities = &gql_generated.ImageVulnerabilitySummary{
|
||||
MaxSeverity: &imageCveSummary.MaxSeverity,
|
||||
Count: &imageCveSummary.Count,
|
||||
MaxSeverity: &imageCveSummary.MaxSeverity,
|
||||
UnknownCount: &imageCveSummary.UnknownCount,
|
||||
LowCount: &imageCveSummary.LowCount,
|
||||
MediumCount: &imageCveSummary.MediumCount,
|
||||
HighCount: &imageCveSummary.HighCount,
|
||||
CriticalCount: &imageCveSummary.CriticalCount,
|
||||
Count: &imageCveSummary.Count,
|
||||
}
|
||||
|
||||
// Check if vulnerability scanning is disabled
|
||||
@ -61,6 +66,11 @@ func updateImageSummaryVulnerabilities(
|
||||
}
|
||||
|
||||
imageSummary.Vulnerabilities.MaxSeverity = &imageCveSummary.MaxSeverity
|
||||
imageSummary.Vulnerabilities.UnknownCount = &imageCveSummary.UnknownCount
|
||||
imageSummary.Vulnerabilities.LowCount = &imageCveSummary.LowCount
|
||||
imageSummary.Vulnerabilities.MediumCount = &imageCveSummary.MediumCount
|
||||
imageSummary.Vulnerabilities.HighCount = &imageCveSummary.HighCount
|
||||
imageSummary.Vulnerabilities.CriticalCount = &imageCveSummary.CriticalCount
|
||||
imageSummary.Vulnerabilities.Count = &imageCveSummary.Count
|
||||
|
||||
for _, manifestSummary := range imageSummary.Manifests {
|
||||
@ -82,8 +92,13 @@ func updateManifestSummaryVulnerabilities(
|
||||
imageCveSummary := cvemodel.ImageCVESummary{}
|
||||
|
||||
manifestSummary.Vulnerabilities = &gql_generated.ImageVulnerabilitySummary{
|
||||
MaxSeverity: &imageCveSummary.MaxSeverity,
|
||||
Count: &imageCveSummary.Count,
|
||||
MaxSeverity: &imageCveSummary.MaxSeverity,
|
||||
UnknownCount: &imageCveSummary.UnknownCount,
|
||||
LowCount: &imageCveSummary.LowCount,
|
||||
MediumCount: &imageCveSummary.MediumCount,
|
||||
HighCount: &imageCveSummary.HighCount,
|
||||
CriticalCount: &imageCveSummary.CriticalCount,
|
||||
Count: &imageCveSummary.Count,
|
||||
}
|
||||
|
||||
// Check if vulnerability scanning is disabled
|
||||
@ -105,5 +120,10 @@ func updateManifestSummaryVulnerabilities(
|
||||
}
|
||||
|
||||
manifestSummary.Vulnerabilities.MaxSeverity = &imageCveSummary.MaxSeverity
|
||||
manifestSummary.Vulnerabilities.UnknownCount = &imageCveSummary.UnknownCount
|
||||
manifestSummary.Vulnerabilities.LowCount = &imageCveSummary.LowCount
|
||||
manifestSummary.Vulnerabilities.MediumCount = &imageCveSummary.MediumCount
|
||||
manifestSummary.Vulnerabilities.HighCount = &imageCveSummary.HighCount
|
||||
manifestSummary.Vulnerabilities.CriticalCount = &imageCveSummary.CriticalCount
|
||||
manifestSummary.Vulnerabilities.Count = &imageCveSummary.Count
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ type CveInfo interface {
|
||||
GetImageListForCVE(ctx context.Context, repo, cveID string) ([]cvemodel.TagInfo, error)
|
||||
GetImageListWithCVEFixed(ctx context.Context, repo, cveID string) ([]cvemodel.TagInfo, error)
|
||||
GetCVEListForImage(ctx context.Context, repo, tag string, searchedCVE string, pageinput cvemodel.PageInput,
|
||||
) ([]cvemodel.CVE, zcommon.PageInfo, error)
|
||||
GetCVESummaryForImageMedia(ctx context.Context, repo, digest, mediaType string) (cvemodel.ImageCVESummary, error)
|
||||
) ([]cvemodel.CVE, cvemodel.ImageCVESummary, zcommon.PageInfo, error)
|
||||
GetCVESummaryForImageMedia(ctx context.Context, repo, digestStr, mediaType string) (cvemodel.ImageCVESummary, error)
|
||||
}
|
||||
|
||||
type Scanner interface {
|
||||
@ -352,75 +352,67 @@ func filterCVEList(cveMap map[string]cvemodel.CVE, searchedCVE string, pageFinde
|
||||
func (cveinfo BaseCveInfo) GetCVEListForImage(ctx context.Context, repo, ref string, searchedCVE string,
|
||||
pageInput cvemodel.PageInput,
|
||||
) (
|
||||
[]cvemodel.CVE, zcommon.PageInfo, error,
|
||||
[]cvemodel.CVE, cvemodel.ImageCVESummary, zcommon.PageInfo, error,
|
||||
) {
|
||||
imageCVESummary := cvemodel.ImageCVESummary{
|
||||
MaxSeverity: cvemodel.SeverityNotScanned,
|
||||
}
|
||||
|
||||
isValidImage, err := cveinfo.Scanner.IsImageFormatScannable(repo, ref)
|
||||
if !isValidImage {
|
||||
cveinfo.Log.Debug().Str("image", repo+":"+ref).Err(err).Msg("image is not scanable")
|
||||
|
||||
return []cvemodel.CVE{}, zcommon.PageInfo{}, err
|
||||
return []cvemodel.CVE{}, imageCVESummary, zcommon.PageInfo{}, err
|
||||
}
|
||||
|
||||
image := zcommon.GetFullImageName(repo, ref)
|
||||
|
||||
cveMap, err := cveinfo.Scanner.ScanImage(ctx, image)
|
||||
if err != nil {
|
||||
return []cvemodel.CVE{}, zcommon.PageInfo{}, err
|
||||
return []cvemodel.CVE{}, imageCVESummary, zcommon.PageInfo{}, err
|
||||
}
|
||||
|
||||
imageCVESummary = initCVESummaryFromCVEMap(cveMap)
|
||||
|
||||
pageFinder, err := NewCvePageFinder(pageInput.Limit, pageInput.Offset, pageInput.SortBy)
|
||||
if err != nil {
|
||||
return []cvemodel.CVE{}, zcommon.PageInfo{}, err
|
||||
return []cvemodel.CVE{}, imageCVESummary, zcommon.PageInfo{}, err
|
||||
}
|
||||
|
||||
filterCVEList(cveMap, searchedCVE, pageFinder)
|
||||
|
||||
cveList, pageInfo := pageFinder.Page()
|
||||
|
||||
return cveList, pageInfo, nil
|
||||
return cveList, imageCVESummary, pageInfo, nil
|
||||
}
|
||||
|
||||
func (cveinfo BaseCveInfo) GetCVESummaryForImageMedia(ctx context.Context, repo, digest, mediaType string,
|
||||
func (cveinfo BaseCveInfo) GetCVESummaryForImageMedia(ctx context.Context, repo, digestStr, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
// There are several cases, expected returned values below:
|
||||
// not scanned yet - max severity "" - cve count 0 - no Errors
|
||||
// not scannable - max severity "" - cve count 0 - has Errors
|
||||
// scannable no issues found - max severity "NONE" - cve count 0 - no Errors
|
||||
// scannable issues found - max severity from Scanner - cve count >0 - no Errors
|
||||
imageCVESummary := cvemodel.ImageCVESummary{
|
||||
Count: 0,
|
||||
MaxSeverity: cvemodel.SeverityNotScanned,
|
||||
}
|
||||
|
||||
// For this call we only look at the scanner cache, we skip the actual scanning to save time
|
||||
if !cveinfo.Scanner.IsResultCached(digest) {
|
||||
isValidImage, err := cveinfo.Scanner.IsImageMediaScannable(repo, digest, mediaType)
|
||||
if !cveinfo.Scanner.IsResultCached(digestStr) {
|
||||
isValidImage, err := cveinfo.Scanner.IsImageMediaScannable(repo, digestStr, mediaType)
|
||||
if !isValidImage {
|
||||
cveinfo.Log.Debug().Str("digest", digest).Str("mediaType", mediaType).
|
||||
cveinfo.Log.Debug().Str("digest", digestStr).Str("mediaType", mediaType).
|
||||
Err(err).Msg("image is not scannable")
|
||||
}
|
||||
|
||||
// Counters are initialized with 0 by default
|
||||
imageCVESummary := cvemodel.ImageCVESummary{
|
||||
MaxSeverity: cvemodel.SeverityNotScanned,
|
||||
}
|
||||
|
||||
return imageCVESummary, err
|
||||
}
|
||||
|
||||
// We will make due with cached results
|
||||
cveMap := cveinfo.Scanner.GetCachedResult(digest)
|
||||
cveMap := cveinfo.Scanner.GetCachedResult(digestStr)
|
||||
|
||||
imageCVESummary.Count = len(cveMap)
|
||||
if imageCVESummary.Count == 0 {
|
||||
imageCVESummary.MaxSeverity = cvemodel.SeverityNone
|
||||
|
||||
return imageCVESummary, nil
|
||||
}
|
||||
|
||||
imageCVESummary.MaxSeverity = cvemodel.SeverityUnknown
|
||||
for _, cve := range cveMap {
|
||||
if cvemodel.CompareSeverities(imageCVESummary.MaxSeverity, cve.Severity) > 0 {
|
||||
imageCVESummary.MaxSeverity = cve.Severity
|
||||
}
|
||||
}
|
||||
|
||||
return imageCVESummary, nil
|
||||
return initCVESummaryFromCVEMap(cveMap), nil
|
||||
}
|
||||
|
||||
func GetFixedTags(allTags, vulnerableTags []cvemodel.TagInfo) []cvemodel.TagInfo {
|
||||
@ -517,3 +509,40 @@ func containsDescriptorInfo(slice []cvemodel.DescriptorInfo, descriptorInfo cvem
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func initCVESummaryFromCVEMap(cveMap map[string]cvemodel.CVE) cvemodel.ImageCVESummary {
|
||||
// Counters are initialized with 0 by default
|
||||
imageCVESummary := cvemodel.ImageCVESummary{
|
||||
MaxSeverity: cvemodel.SeverityNotScanned,
|
||||
}
|
||||
|
||||
imageCVESummary.Count = len(cveMap)
|
||||
if imageCVESummary.Count == 0 {
|
||||
imageCVESummary.MaxSeverity = cvemodel.SeverityNone
|
||||
|
||||
return imageCVESummary
|
||||
}
|
||||
|
||||
imageCVESummary.MaxSeverity = cvemodel.SeverityUnknown
|
||||
|
||||
for _, cve := range cveMap {
|
||||
switch cve.Severity {
|
||||
case cvemodel.SeverityUnknown:
|
||||
imageCVESummary.UnknownCount += 1
|
||||
case cvemodel.SeverityLow:
|
||||
imageCVESummary.LowCount += 1
|
||||
case cvemodel.SeverityMedium:
|
||||
imageCVESummary.MediumCount += 1
|
||||
case cvemodel.SeverityHigh:
|
||||
imageCVESummary.HighCount += 1
|
||||
case cvemodel.SeverityCritical:
|
||||
imageCVESummary.CriticalCount += 1
|
||||
}
|
||||
|
||||
if cvemodel.CompareSeverities(imageCVESummary.MaxSeverity, cve.Severity) > 0 {
|
||||
imageCVESummary.MaxSeverity = cve.Severity
|
||||
}
|
||||
}
|
||||
|
||||
return imageCVESummary
|
||||
}
|
||||
|
@ -754,6 +754,7 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
const repo5 = "repo5"
|
||||
const repo6 = "repo6"
|
||||
const repo7 = "repo7"
|
||||
const repo8 = "repo8"
|
||||
const repo100 = "repo100"
|
||||
const repoMultiarch = "repoIndex"
|
||||
|
||||
@ -833,6 +834,13 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
err = metaDB.SetRepoReference(context.Background(), repo7, "1.0.0", image71.AsImageMeta())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Create image with vulnerabilities of all severities
|
||||
image81 := CreateImageWith().DefaultLayers().
|
||||
ImageConfig(ispec.Image{Created: DateRef(2020, 12, 1, 12, 0, 0, 0, time.UTC)}).Build()
|
||||
|
||||
err = metaDB.SetRepoReference(context.Background(), repo8, "1.0.0", image81.AsImageMeta())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// create multiarch image with vulnerabilities
|
||||
multiarchImage := CreateRandomMultiarch()
|
||||
|
||||
@ -891,6 +899,10 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
image71Media := image71.ManifestDescriptor.MediaType
|
||||
image71Name := repo7 + ":1.0.0"
|
||||
imageMap[image71Name] = image71Digest
|
||||
image81Digest := image81.ManifestDescriptor.Digest.String()
|
||||
image81Media := image81.ManifestDescriptor.MediaType
|
||||
image81Name := repo8 + ":1.0.0"
|
||||
imageMap[image81Name] = image81Digest
|
||||
indexDigest := multiarchImage.IndexDescriptor.Digest.String()
|
||||
indexMedia := multiarchImage.IndexDescriptor.MediaType
|
||||
indexName := repoMultiarch + ":tagIndex"
|
||||
@ -1042,6 +1054,57 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
return result, nil
|
||||
}
|
||||
|
||||
if repo == repo8 && ref == image81Digest {
|
||||
result := map[string]cvemodel.CVE{
|
||||
"CVE0": {
|
||||
ID: "CVE0",
|
||||
Severity: "UNKNOWN",
|
||||
Title: "Title CVE0",
|
||||
Description: "Description CVE0",
|
||||
},
|
||||
"CVE1": {
|
||||
ID: "CVE1",
|
||||
Severity: "MEDIUM",
|
||||
Title: "Title CVE1",
|
||||
Description: "Description CVE1",
|
||||
},
|
||||
"CVE2": {
|
||||
ID: "CVE2",
|
||||
Severity: "HIGH",
|
||||
Title: "Title CVE2",
|
||||
Description: "Description CVE2",
|
||||
},
|
||||
"CVE3": {
|
||||
ID: "CVE3",
|
||||
Severity: "LOW",
|
||||
Title: "Title CVE3",
|
||||
Description: "Description CVE3",
|
||||
},
|
||||
"CVE4": {
|
||||
ID: "CVE4",
|
||||
Severity: "CRITICAL",
|
||||
Title: "Title CVE4",
|
||||
Description: "Description CVE4",
|
||||
},
|
||||
"CVE5": {
|
||||
ID: "CVE5",
|
||||
Severity: "CRITICAL",
|
||||
Title: "Title CVE5",
|
||||
Description: "Description CVE5",
|
||||
},
|
||||
"CVE6": {
|
||||
ID: "CVE6",
|
||||
Severity: "LOW",
|
||||
Title: "Title CVE6",
|
||||
Description: "Description CVE6",
|
||||
},
|
||||
}
|
||||
|
||||
cache.Add(ref, result)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// By default the image has no vulnerabilities
|
||||
result = map[string]cvemodel.CVE{}
|
||||
cache.Add(ref, result)
|
||||
@ -1130,14 +1193,21 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
ctx := context.Background()
|
||||
|
||||
// Image is found
|
||||
cveList, pageInfo, err := cveInfo.GetCVEListForImage(ctx, repo1, "0.1.0", "", pageInput)
|
||||
cveList, cveSummary, pageInfo, err := cveInfo.GetCVEListForImage(ctx, repo1, "0.1.0", "", pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveList), ShouldEqual, 1)
|
||||
So(cveList[0].ID, ShouldEqual, "CVE1")
|
||||
So(pageInfo.ItemCount, ShouldEqual, 1)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 1)
|
||||
So(cveSummary.Count, ShouldEqual, 1)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "MEDIUM")
|
||||
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo1, "1.0.0", "", pageInput)
|
||||
cveList, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo1, "1.0.0", "", pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveList), ShouldEqual, 3)
|
||||
So(cveList[0].ID, ShouldEqual, "CVE2")
|
||||
@ -1145,116 +1215,249 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
So(cveList[2].ID, ShouldEqual, "CVE3")
|
||||
So(pageInfo.ItemCount, ShouldEqual, 3)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 3)
|
||||
So(cveSummary.Count, ShouldEqual, 3)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 1)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "HIGH")
|
||||
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo1, "1.0.1", "", pageInput)
|
||||
cveList, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo1, "1.0.1", "", pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveList), ShouldEqual, 2)
|
||||
So(cveList[0].ID, ShouldEqual, "CVE1")
|
||||
So(cveList[1].ID, ShouldEqual, "CVE3")
|
||||
So(pageInfo.ItemCount, ShouldEqual, 2)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 2)
|
||||
So(cveSummary.Count, ShouldEqual, 2)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "MEDIUM")
|
||||
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo1, "1.1.0", "", pageInput)
|
||||
cveList, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo1, "1.1.0", "", pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveList), ShouldEqual, 1)
|
||||
So(cveList[0].ID, ShouldEqual, "CVE3")
|
||||
So(pageInfo.ItemCount, ShouldEqual, 1)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 1)
|
||||
So(cveSummary.Count, ShouldEqual, 1)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "LOW")
|
||||
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo6, "1.0.0", "", pageInput)
|
||||
cveList, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo6, "1.0.0", "", pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveList), ShouldEqual, 0)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 0)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "NONE")
|
||||
|
||||
cveList, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo8, "1.0.0", "", pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveList), ShouldEqual, 7)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 7)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 7)
|
||||
So(cveSummary.Count, ShouldEqual, 7)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 1)
|
||||
So(cveSummary.LowCount, ShouldEqual, 2)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 1)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 2)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
|
||||
// Image is multiarch
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repoMultiarch, "tagIndex", "", pageInput)
|
||||
cveList, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repoMultiarch, "tagIndex", "", pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveList), ShouldEqual, 1)
|
||||
So(cveList[0].ID, ShouldEqual, "CVE1")
|
||||
So(pageInfo.ItemCount, ShouldEqual, 1)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 1)
|
||||
So(cveSummary.Count, ShouldEqual, 1)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "MEDIUM")
|
||||
|
||||
// Image is not scannable
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo2, "1.0.0", "", pageInput)
|
||||
cveList, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo2, "1.0.0", "", pageInput)
|
||||
So(err, ShouldEqual, zerr.ErrScanNotSupported)
|
||||
So(len(cveList), ShouldEqual, 0)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 0)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
// Tag is not found
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo3, "1.0.0", "", pageInput)
|
||||
cveList, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo3, "1.0.0", "", pageInput)
|
||||
So(err, ShouldEqual, zerr.ErrTagMetaNotFound)
|
||||
So(len(cveList), ShouldEqual, 0)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 0)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
// Scan failed
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo7, "1.0.0", "", pageInput)
|
||||
cveList, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo7, "1.0.0", "", pageInput)
|
||||
So(err, ShouldEqual, ErrFailedScan)
|
||||
So(len(cveList), ShouldEqual, 0)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 0)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
// Tag is not found
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo-with-bad-tag-digest", "tag", "", pageInput)
|
||||
cveList, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo-with-bad-tag-digest", "tag", "", pageInput)
|
||||
So(err, ShouldEqual, zerr.ErrImageMetaNotFound)
|
||||
So(len(cveList), ShouldEqual, 0)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 0)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
// Repo is not found
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo100, "1.0.0", "", pageInput)
|
||||
cveList, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo100, "1.0.0", "", pageInput)
|
||||
So(err, ShouldEqual, zerr.ErrRepoMetaNotFound)
|
||||
So(len(cveList), ShouldEqual, 0)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 0)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
// By this point the cache should already be pupulated by previous function calls
|
||||
t.Log("\nTest GetCVESummaryForImage\n")
|
||||
|
||||
// Image is found
|
||||
cveSummary, err := cveInfo.GetCVESummaryForImageMedia(ctx, repo1, image11Digest, image11Media)
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo1, image11Digest, image11Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 1)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "MEDIUM")
|
||||
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo1, image12Digest, image12Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 3)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 1)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "HIGH")
|
||||
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo1, image14Digest, image14Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 2)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "MEDIUM")
|
||||
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo1, image13Digest, image13Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 1)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "LOW")
|
||||
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo6, image61Digest, image61Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "NONE")
|
||||
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo8, image81Digest, image81Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 7)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 1)
|
||||
So(cveSummary.LowCount, ShouldEqual, 2)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 1)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 2)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
|
||||
// Image is multiarch
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repoMultiarch, indexDigest, indexMedia)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 1)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "MEDIUM")
|
||||
|
||||
// Image is not scannable
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo2, image21Digest, image21Media)
|
||||
So(err, ShouldEqual, zerr.ErrScanNotSupported)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
// Scan failed
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo5, image71Digest, image71Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
// Repo is not found
|
||||
@ -1262,6 +1465,11 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
godigest.FromString("missing_digest").String(), ispec.MediaTypeImageManifest)
|
||||
So(err, ShouldEqual, zerr.ErrRepoMetaNotFound)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
t.Log("\nTest GetImageListWithCVEFixed\n")
|
||||
@ -1366,13 +1574,25 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo1, image11Digest, image11Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo1, "0.1.0", "", pageInput)
|
||||
cveList, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo1, "0.1.0", "", pageInput)
|
||||
So(err, ShouldNotBeNil)
|
||||
So(cveList, ShouldBeEmpty)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 0)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 0)
|
||||
So(cveSummary.LowCount, ShouldEqual, 0)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 0)
|
||||
So(cveSummary.HighCount, ShouldEqual, 0)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
tagList, err = cveInfo.GetImageListWithCVEFixed(ctx, repo1, "CVE1")
|
||||
// CVE is not considered fixed as scan is not possible
|
||||
|
@ -7,8 +7,13 @@ import (
|
||||
)
|
||||
|
||||
type ImageCVESummary struct {
|
||||
Count int
|
||||
MaxSeverity string
|
||||
Count int
|
||||
UnknownCount int
|
||||
LowCount int
|
||||
MediumCount int
|
||||
HighCount int
|
||||
CriticalCount int
|
||||
MaxSeverity string
|
||||
}
|
||||
|
||||
//nolint:tagliatelle // graphQL schema
|
||||
|
@ -140,22 +140,36 @@ func TestCVEPagination(t *testing.T) {
|
||||
Convey("Page", func() {
|
||||
Convey("defaults", func() {
|
||||
// By default expect unlimitted results sorted by severity
|
||||
cves, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{})
|
||||
cves, cveSummary, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{})
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cves), ShouldEqual, 5)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 5)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 5)
|
||||
So(cveSummary.Count, ShouldEqual, 5)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 1)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 1)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 1)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
previousSeverity := 4
|
||||
for _, cve := range cves {
|
||||
So(severityToInt[cve.Severity], ShouldBeLessThanOrEqualTo, previousSeverity)
|
||||
previousSeverity = severityToInt[cve.Severity]
|
||||
}
|
||||
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "", cvemodel.PageInput{})
|
||||
cves, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "", cvemodel.PageInput{})
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cves), ShouldEqual, 30)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 30)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 30)
|
||||
So(cveSummary.Count, ShouldEqual, 30)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 6)
|
||||
So(cveSummary.LowCount, ShouldEqual, 6)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 6)
|
||||
So(cveSummary.HighCount, ShouldEqual, 6)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 6)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
previousSeverity = 4
|
||||
for _, cve := range cves {
|
||||
So(severityToInt[cve.Severity], ShouldBeLessThanOrEqualTo, previousSeverity)
|
||||
@ -169,44 +183,72 @@ func TestCVEPagination(t *testing.T) {
|
||||
cveIds = append(cveIds, fmt.Sprintf("CVE%d", i))
|
||||
}
|
||||
|
||||
cves, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "",
|
||||
cves, cveSummary, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "",
|
||||
cvemodel.PageInput{SortBy: cveinfo.AlphabeticAsc})
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cves), ShouldEqual, 5)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 5)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 5)
|
||||
So(cveSummary.Count, ShouldEqual, 5)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 1)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 1)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 1)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
for i, cve := range cves {
|
||||
So(cve.ID, ShouldEqual, cveIds[i])
|
||||
}
|
||||
|
||||
sort.Strings(cveIds)
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "",
|
||||
cves, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "",
|
||||
cvemodel.PageInput{SortBy: cveinfo.AlphabeticAsc})
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cves), ShouldEqual, 30)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 30)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 30)
|
||||
So(cveSummary.Count, ShouldEqual, 30)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 6)
|
||||
So(cveSummary.LowCount, ShouldEqual, 6)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 6)
|
||||
So(cveSummary.HighCount, ShouldEqual, 6)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 6)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
for i, cve := range cves {
|
||||
So(cve.ID, ShouldEqual, cveIds[i])
|
||||
}
|
||||
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(cveIds)))
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "",
|
||||
cves, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "",
|
||||
cvemodel.PageInput{SortBy: cveinfo.AlphabeticDsc})
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cves), ShouldEqual, 30)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 30)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 30)
|
||||
So(cveSummary.Count, ShouldEqual, 30)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 6)
|
||||
So(cveSummary.LowCount, ShouldEqual, 6)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 6)
|
||||
So(cveSummary.HighCount, ShouldEqual, 6)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 6)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
for i, cve := range cves {
|
||||
So(cve.ID, ShouldEqual, cveIds[i])
|
||||
}
|
||||
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "",
|
||||
cves, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "",
|
||||
cvemodel.PageInput{SortBy: cveinfo.SeverityDsc})
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cves), ShouldEqual, 30)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 30)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 30)
|
||||
So(cveSummary.Count, ShouldEqual, 30)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 6)
|
||||
So(cveSummary.LowCount, ShouldEqual, 6)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 6)
|
||||
So(cveSummary.HighCount, ShouldEqual, 6)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 6)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
previousSeverity := 4
|
||||
for _, cve := range cves {
|
||||
So(severityToInt[cve.Severity], ShouldBeLessThanOrEqualTo, previousSeverity)
|
||||
@ -220,7 +262,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
cveIds = append(cveIds, fmt.Sprintf("CVE%d", i))
|
||||
}
|
||||
|
||||
cves, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
cves, cveSummary, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
Limit: 3,
|
||||
Offset: 1,
|
||||
SortBy: cveinfo.AlphabeticAsc,
|
||||
@ -233,8 +275,15 @@ func TestCVEPagination(t *testing.T) {
|
||||
So(cves[0].ID, ShouldEqual, "CVE1") // CVE0 is first ID and is not part of the page
|
||||
So(cves[1].ID, ShouldEqual, "CVE2")
|
||||
So(cves[2].ID, ShouldEqual, "CVE3")
|
||||
So(cveSummary.Count, ShouldEqual, 5)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 1)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 1)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 1)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
cves, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
Limit: 2,
|
||||
Offset: 1,
|
||||
SortBy: cveinfo.AlphabeticDsc,
|
||||
@ -246,8 +295,15 @@ func TestCVEPagination(t *testing.T) {
|
||||
So(pageInfo.TotalCount, ShouldEqual, 5)
|
||||
So(cves[0].ID, ShouldEqual, "CVE3")
|
||||
So(cves[1].ID, ShouldEqual, "CVE2")
|
||||
So(cveSummary.Count, ShouldEqual, 5)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 1)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 1)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 1)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
cves, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
Limit: 3,
|
||||
Offset: 1,
|
||||
SortBy: cveinfo.SeverityDsc,
|
||||
@ -257,6 +313,13 @@ func TestCVEPagination(t *testing.T) {
|
||||
So(len(cves), ShouldEqual, 3)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 3)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 5)
|
||||
So(cveSummary.Count, ShouldEqual, 5)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 1)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 1)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 1)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
previousSeverity := 4
|
||||
for _, cve := range cves {
|
||||
So(severityToInt[cve.Severity], ShouldBeLessThanOrEqualTo, previousSeverity)
|
||||
@ -264,7 +327,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
}
|
||||
|
||||
sort.Strings(cveIds)
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "", cvemodel.PageInput{
|
||||
cves, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "", cvemodel.PageInput{
|
||||
Limit: 5,
|
||||
Offset: 20,
|
||||
SortBy: cveinfo.AlphabeticAsc,
|
||||
@ -274,13 +337,20 @@ func TestCVEPagination(t *testing.T) {
|
||||
So(len(cves), ShouldEqual, 5)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 5)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 30)
|
||||
So(cveSummary.Count, ShouldEqual, 30)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 6)
|
||||
So(cveSummary.LowCount, ShouldEqual, 6)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 6)
|
||||
So(cveSummary.HighCount, ShouldEqual, 6)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 6)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
for i, cve := range cves {
|
||||
So(cve.ID, ShouldEqual, cveIds[i+20])
|
||||
}
|
||||
})
|
||||
|
||||
Convey("limit > len(cves)", func() {
|
||||
cves, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
cves, cveSummary, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
Limit: 6,
|
||||
Offset: 3,
|
||||
SortBy: cveinfo.AlphabeticAsc,
|
||||
@ -292,8 +362,15 @@ func TestCVEPagination(t *testing.T) {
|
||||
So(pageInfo.TotalCount, ShouldEqual, 5)
|
||||
So(cves[0].ID, ShouldEqual, "CVE3")
|
||||
So(cves[1].ID, ShouldEqual, "CVE4")
|
||||
So(cveSummary.Count, ShouldEqual, 5)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 1)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 1)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 1)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
cves, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
Limit: 6,
|
||||
Offset: 3,
|
||||
SortBy: cveinfo.AlphabeticDsc,
|
||||
@ -305,8 +382,15 @@ func TestCVEPagination(t *testing.T) {
|
||||
So(pageInfo.TotalCount, ShouldEqual, 5)
|
||||
So(cves[0].ID, ShouldEqual, "CVE1")
|
||||
So(cves[1].ID, ShouldEqual, "CVE0")
|
||||
So(cveSummary.Count, ShouldEqual, 5)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 1)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 1)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 1)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
cves, cveSummary, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
Limit: 6,
|
||||
Offset: 3,
|
||||
SortBy: cveinfo.SeverityDsc,
|
||||
@ -316,6 +400,13 @@ func TestCVEPagination(t *testing.T) {
|
||||
So(len(cves), ShouldEqual, 2)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 2)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 5)
|
||||
So(cveSummary.Count, ShouldEqual, 5)
|
||||
So(cveSummary.UnknownCount, ShouldEqual, 1)
|
||||
So(cveSummary.LowCount, ShouldEqual, 1)
|
||||
So(cveSummary.MediumCount, ShouldEqual, 1)
|
||||
So(cveSummary.HighCount, ShouldEqual, 1)
|
||||
So(cveSummary.CriticalCount, ShouldEqual, 1)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
previousSeverity := 4
|
||||
for _, cve := range cves {
|
||||
So(severityToInt[cve.Severity], ShouldBeLessThanOrEqualTo, previousSeverity)
|
||||
|
@ -62,6 +62,7 @@ type ComplexityRoot struct {
|
||||
CVEResultForImage struct {
|
||||
CVEList func(childComplexity int) int
|
||||
Page func(childComplexity int) int
|
||||
Summary func(childComplexity int) int
|
||||
Tag func(childComplexity int) int
|
||||
}
|
||||
|
||||
@ -105,8 +106,13 @@ type ComplexityRoot struct {
|
||||
}
|
||||
|
||||
ImageVulnerabilitySummary struct {
|
||||
Count func(childComplexity int) int
|
||||
MaxSeverity func(childComplexity int) int
|
||||
Count func(childComplexity int) int
|
||||
CriticalCount func(childComplexity int) int
|
||||
HighCount func(childComplexity int) int
|
||||
LowCount func(childComplexity int) int
|
||||
MaxSeverity func(childComplexity int) int
|
||||
MediumCount func(childComplexity int) int
|
||||
UnknownCount func(childComplexity int) int
|
||||
}
|
||||
|
||||
LayerHistory struct {
|
||||
@ -318,6 +324,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.CVEResultForImage.Page(childComplexity), true
|
||||
|
||||
case "CVEResultForImage.Summary":
|
||||
if e.complexity.CVEResultForImage.Summary == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.CVEResultForImage.Summary(childComplexity), true
|
||||
|
||||
case "CVEResultForImage.Tag":
|
||||
if e.complexity.CVEResultForImage.Tag == nil {
|
||||
break
|
||||
@ -542,6 +555,27 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.ImageVulnerabilitySummary.Count(childComplexity), true
|
||||
|
||||
case "ImageVulnerabilitySummary.CriticalCount":
|
||||
if e.complexity.ImageVulnerabilitySummary.CriticalCount == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.ImageVulnerabilitySummary.CriticalCount(childComplexity), true
|
||||
|
||||
case "ImageVulnerabilitySummary.HighCount":
|
||||
if e.complexity.ImageVulnerabilitySummary.HighCount == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.ImageVulnerabilitySummary.HighCount(childComplexity), true
|
||||
|
||||
case "ImageVulnerabilitySummary.LowCount":
|
||||
if e.complexity.ImageVulnerabilitySummary.LowCount == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.ImageVulnerabilitySummary.LowCount(childComplexity), true
|
||||
|
||||
case "ImageVulnerabilitySummary.MaxSeverity":
|
||||
if e.complexity.ImageVulnerabilitySummary.MaxSeverity == nil {
|
||||
break
|
||||
@ -549,6 +583,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.ImageVulnerabilitySummary.MaxSeverity(childComplexity), true
|
||||
|
||||
case "ImageVulnerabilitySummary.MediumCount":
|
||||
if e.complexity.ImageVulnerabilitySummary.MediumCount == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.ImageVulnerabilitySummary.MediumCount(childComplexity), true
|
||||
|
||||
case "ImageVulnerabilitySummary.UnknownCount":
|
||||
if e.complexity.ImageVulnerabilitySummary.UnknownCount == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.ImageVulnerabilitySummary.UnknownCount(childComplexity), true
|
||||
|
||||
case "LayerHistory.HistoryDescription":
|
||||
if e.complexity.LayerHistory.HistoryDescription == nil {
|
||||
break
|
||||
@ -1164,6 +1212,7 @@ A timestamp
|
||||
"""
|
||||
scalar Time
|
||||
|
||||
|
||||
"""
|
||||
Contains the tag of the image and a list of CVEs
|
||||
"""
|
||||
@ -1177,6 +1226,10 @@ type CVEResultForImage {
|
||||
"""
|
||||
CVEList: [CVE]
|
||||
"""
|
||||
Summary of the findings for this image
|
||||
"""
|
||||
Summary: ImageVulnerabilitySummary
|
||||
"""
|
||||
The CVE pagination information, see PageInfo object for more details
|
||||
"""
|
||||
Page: PageInfo
|
||||
@ -1430,6 +1483,26 @@ type ImageVulnerabilitySummary {
|
||||
Count of all CVEs found in this image
|
||||
"""
|
||||
Count: Int
|
||||
"""
|
||||
Coresponds to CVSS 3 score NONE
|
||||
"""
|
||||
UnknownCount: Int
|
||||
"""
|
||||
Coresponds to CVSS 3 score LOW
|
||||
"""
|
||||
LowCount: Int
|
||||
"""
|
||||
Coresponds to CVSS 3 score MEDIUM
|
||||
"""
|
||||
MediumCount: Int
|
||||
"""
|
||||
Coresponds to CVSS 3 score HIGH
|
||||
"""
|
||||
HighCount: Int
|
||||
"""
|
||||
Coresponds to CVSS 3 score CRITICAL
|
||||
"""
|
||||
CriticalCount: Int
|
||||
}
|
||||
|
||||
"""
|
||||
@ -2761,6 +2834,63 @@ func (ec *executionContext) fieldContext_CVEResultForImage_CVEList(ctx context.C
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _CVEResultForImage_Summary(ctx context.Context, field graphql.CollectedField, obj *CVEResultForImage) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_CVEResultForImage_Summary(ctx, field)
|
||||
if err != nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.Summary, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*ImageVulnerabilitySummary)
|
||||
fc.Result = res
|
||||
return ec.marshalOImageVulnerabilitySummary2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐImageVulnerabilitySummary(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_CVEResultForImage_Summary(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "CVEResultForImage",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
switch field.Name {
|
||||
case "MaxSeverity":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_MaxSeverity(ctx, field)
|
||||
case "Count":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_Count(ctx, field)
|
||||
case "UnknownCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_UnknownCount(ctx, field)
|
||||
case "LowCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_LowCount(ctx, field)
|
||||
case "MediumCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_MediumCount(ctx, field)
|
||||
case "HighCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_HighCount(ctx, field)
|
||||
case "CriticalCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_CriticalCount(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type ImageVulnerabilitySummary", field.Name)
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _CVEResultForImage_Page(ctx context.Context, field graphql.CollectedField, obj *CVEResultForImage) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_CVEResultForImage_Page(ctx, field)
|
||||
if err != nil {
|
||||
@ -4071,6 +4201,16 @@ func (ec *executionContext) fieldContext_ImageSummary_Vulnerabilities(ctx contex
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_MaxSeverity(ctx, field)
|
||||
case "Count":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_Count(ctx, field)
|
||||
case "UnknownCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_UnknownCount(ctx, field)
|
||||
case "LowCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_LowCount(ctx, field)
|
||||
case "MediumCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_MediumCount(ctx, field)
|
||||
case "HighCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_HighCount(ctx, field)
|
||||
case "CriticalCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_CriticalCount(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type ImageVulnerabilitySummary", field.Name)
|
||||
},
|
||||
@ -4254,6 +4394,211 @@ func (ec *executionContext) fieldContext_ImageVulnerabilitySummary_Count(ctx con
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _ImageVulnerabilitySummary_UnknownCount(ctx context.Context, field graphql.CollectedField, obj *ImageVulnerabilitySummary) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_ImageVulnerabilitySummary_UnknownCount(ctx, field)
|
||||
if err != nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.UnknownCount, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*int)
|
||||
fc.Result = res
|
||||
return ec.marshalOInt2ᚖint(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_ImageVulnerabilitySummary_UnknownCount(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "ImageVulnerabilitySummary",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type Int does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _ImageVulnerabilitySummary_LowCount(ctx context.Context, field graphql.CollectedField, obj *ImageVulnerabilitySummary) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_ImageVulnerabilitySummary_LowCount(ctx, field)
|
||||
if err != nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.LowCount, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*int)
|
||||
fc.Result = res
|
||||
return ec.marshalOInt2ᚖint(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_ImageVulnerabilitySummary_LowCount(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "ImageVulnerabilitySummary",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type Int does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _ImageVulnerabilitySummary_MediumCount(ctx context.Context, field graphql.CollectedField, obj *ImageVulnerabilitySummary) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_ImageVulnerabilitySummary_MediumCount(ctx, field)
|
||||
if err != nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.MediumCount, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*int)
|
||||
fc.Result = res
|
||||
return ec.marshalOInt2ᚖint(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_ImageVulnerabilitySummary_MediumCount(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "ImageVulnerabilitySummary",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type Int does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _ImageVulnerabilitySummary_HighCount(ctx context.Context, field graphql.CollectedField, obj *ImageVulnerabilitySummary) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_ImageVulnerabilitySummary_HighCount(ctx, field)
|
||||
if err != nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.HighCount, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*int)
|
||||
fc.Result = res
|
||||
return ec.marshalOInt2ᚖint(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_ImageVulnerabilitySummary_HighCount(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "ImageVulnerabilitySummary",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type Int does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _ImageVulnerabilitySummary_CriticalCount(ctx context.Context, field graphql.CollectedField, obj *ImageVulnerabilitySummary) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_ImageVulnerabilitySummary_CriticalCount(ctx, field)
|
||||
if err != nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.CriticalCount, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*int)
|
||||
fc.Result = res
|
||||
return ec.marshalOInt2ᚖint(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_ImageVulnerabilitySummary_CriticalCount(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "ImageVulnerabilitySummary",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type Int does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _LayerHistory_Layer(ctx context.Context, field graphql.CollectedField, obj *LayerHistory) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_LayerHistory_Layer(ctx, field)
|
||||
if err != nil {
|
||||
@ -4912,6 +5257,16 @@ func (ec *executionContext) fieldContext_ManifestSummary_Vulnerabilities(ctx con
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_MaxSeverity(ctx, field)
|
||||
case "Count":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_Count(ctx, field)
|
||||
case "UnknownCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_UnknownCount(ctx, field)
|
||||
case "LowCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_LowCount(ctx, field)
|
||||
case "MediumCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_MediumCount(ctx, field)
|
||||
case "HighCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_HighCount(ctx, field)
|
||||
case "CriticalCount":
|
||||
return ec.fieldContext_ImageVulnerabilitySummary_CriticalCount(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type ImageVulnerabilitySummary", field.Name)
|
||||
},
|
||||
@ -5599,6 +5954,8 @@ func (ec *executionContext) fieldContext_Query_CVEListForImage(ctx context.Conte
|
||||
return ec.fieldContext_CVEResultForImage_Tag(ctx, field)
|
||||
case "CVEList":
|
||||
return ec.fieldContext_CVEResultForImage_CVEList(ctx, field)
|
||||
case "Summary":
|
||||
return ec.fieldContext_CVEResultForImage_Summary(ctx, field)
|
||||
case "Page":
|
||||
return ec.fieldContext_CVEResultForImage_Page(ctx, field)
|
||||
}
|
||||
@ -9553,6 +9910,8 @@ func (ec *executionContext) _CVEResultForImage(ctx context.Context, sel ast.Sele
|
||||
out.Values[i] = ec._CVEResultForImage_Tag(ctx, field, obj)
|
||||
case "CVEList":
|
||||
out.Values[i] = ec._CVEResultForImage_CVEList(ctx, field, obj)
|
||||
case "Summary":
|
||||
out.Values[i] = ec._CVEResultForImage_Summary(ctx, field, obj)
|
||||
case "Page":
|
||||
out.Values[i] = ec._CVEResultForImage_Page(ctx, field, obj)
|
||||
default:
|
||||
@ -9755,6 +10114,16 @@ func (ec *executionContext) _ImageVulnerabilitySummary(ctx context.Context, sel
|
||||
out.Values[i] = ec._ImageVulnerabilitySummary_MaxSeverity(ctx, field, obj)
|
||||
case "Count":
|
||||
out.Values[i] = ec._ImageVulnerabilitySummary_Count(ctx, field, obj)
|
||||
case "UnknownCount":
|
||||
out.Values[i] = ec._ImageVulnerabilitySummary_UnknownCount(ctx, field, obj)
|
||||
case "LowCount":
|
||||
out.Values[i] = ec._ImageVulnerabilitySummary_LowCount(ctx, field, obj)
|
||||
case "MediumCount":
|
||||
out.Values[i] = ec._ImageVulnerabilitySummary_MediumCount(ctx, field, obj)
|
||||
case "HighCount":
|
||||
out.Values[i] = ec._ImageVulnerabilitySummary_HighCount(ctx, field, obj)
|
||||
case "CriticalCount":
|
||||
out.Values[i] = ec._ImageVulnerabilitySummary_CriticalCount(ctx, field, obj)
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ type CVEResultForImage struct {
|
||||
Tag *string `json:"Tag,omitempty"`
|
||||
// List of CVE objects which affect this specific image:tag
|
||||
CVEList []*Cve `json:"CVEList,omitempty"`
|
||||
// Summary of the findings for this image
|
||||
Summary *ImageVulnerabilitySummary `json:"Summary,omitempty"`
|
||||
// The CVE pagination information, see PageInfo object for more details
|
||||
Page *PageInfo `json:"Page,omitempty"`
|
||||
}
|
||||
@ -144,6 +146,16 @@ type ImageVulnerabilitySummary struct {
|
||||
MaxSeverity *string `json:"MaxSeverity,omitempty"`
|
||||
// Count of all CVEs found in this image
|
||||
Count *int `json:"Count,omitempty"`
|
||||
// Coresponds to CVSS 3 score NONE
|
||||
UnknownCount *int `json:"UnknownCount,omitempty"`
|
||||
// Coresponds to CVSS 3 score LOW
|
||||
LowCount *int `json:"LowCount,omitempty"`
|
||||
// Coresponds to CVSS 3 score MEDIUM
|
||||
MediumCount *int `json:"MediumCount,omitempty"`
|
||||
// Coresponds to CVSS 3 score HIGH
|
||||
HighCount *int `json:"HighCount,omitempty"`
|
||||
// Coresponds to CVSS 3 score CRITICAL
|
||||
CriticalCount *int `json:"CriticalCount,omitempty"`
|
||||
}
|
||||
|
||||
// Information about how/when a layer was built
|
||||
|
@ -216,7 +216,8 @@ func getCVEListForImage(
|
||||
return &gql_generated.CVEResultForImage{}, gqlerror.Errorf("no reference provided")
|
||||
}
|
||||
|
||||
cveList, pageInfo, err := cveInfo.GetCVEListForImage(ctx, repo, ref, searchedCVE, pageInput)
|
||||
cveList, imageCveSummary, pageInfo, err := cveInfo.GetCVEListForImage(ctx, repo, ref,
|
||||
searchedCVE, pageInput)
|
||||
if err != nil {
|
||||
return &gql_generated.CVEResultForImage{}, err
|
||||
}
|
||||
@ -259,6 +260,15 @@ func getCVEListForImage(
|
||||
return &gql_generated.CVEResultForImage{
|
||||
Tag: &ref,
|
||||
CVEList: cveids,
|
||||
Summary: &gql_generated.ImageVulnerabilitySummary{
|
||||
MaxSeverity: &imageCveSummary.MaxSeverity,
|
||||
UnknownCount: &imageCveSummary.UnknownCount,
|
||||
LowCount: &imageCveSummary.LowCount,
|
||||
MediumCount: &imageCveSummary.MediumCount,
|
||||
HighCount: &imageCveSummary.HighCount,
|
||||
CriticalCount: &imageCveSummary.CriticalCount,
|
||||
Count: &imageCveSummary.Count,
|
||||
},
|
||||
Page: &gql_generated.PageInfo{
|
||||
TotalCount: pageInfo.TotalCount,
|
||||
ItemCount: pageInfo.ItemCount,
|
||||
|
@ -10,6 +10,7 @@ A timestamp
|
||||
"""
|
||||
scalar Time
|
||||
|
||||
|
||||
"""
|
||||
Contains the tag of the image and a list of CVEs
|
||||
"""
|
||||
@ -23,6 +24,10 @@ type CVEResultForImage {
|
||||
"""
|
||||
CVEList: [CVE]
|
||||
"""
|
||||
Summary of the findings for this image
|
||||
"""
|
||||
Summary: ImageVulnerabilitySummary
|
||||
"""
|
||||
The CVE pagination information, see PageInfo object for more details
|
||||
"""
|
||||
Page: PageInfo
|
||||
@ -276,6 +281,26 @@ type ImageVulnerabilitySummary {
|
||||
Count of all CVEs found in this image
|
||||
"""
|
||||
Count: Int
|
||||
"""
|
||||
Coresponds to CVSS 3 score NONE
|
||||
"""
|
||||
UnknownCount: Int
|
||||
"""
|
||||
Coresponds to CVSS 3 score LOW
|
||||
"""
|
||||
LowCount: Int
|
||||
"""
|
||||
Coresponds to CVSS 3 score MEDIUM
|
||||
"""
|
||||
MediumCount: Int
|
||||
"""
|
||||
Coresponds to CVSS 3 score HIGH
|
||||
"""
|
||||
HighCount: Int
|
||||
"""
|
||||
Coresponds to CVSS 3 score CRITICAL
|
||||
"""
|
||||
CriticalCount: Int
|
||||
}
|
||||
|
||||
"""
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
|
||||
guuid "github.com/gofrs/uuid"
|
||||
regTypes "github.com/google/go-containerregistry/pkg/v1/types"
|
||||
notreg "github.com/notaryproject/notation-go/registry"
|
||||
@ -530,6 +529,11 @@ func TestRepoListWithNewestImage(t *testing.T) {
|
||||
Tag
|
||||
Vulnerabilities{
|
||||
MaxSeverity
|
||||
UnknownCount
|
||||
LowCount
|
||||
MediumCount
|
||||
HighCount
|
||||
CriticalCount
|
||||
Count
|
||||
}
|
||||
}
|
||||
@ -551,6 +555,11 @@ func TestRepoListWithNewestImage(t *testing.T) {
|
||||
images = responseStruct.Results
|
||||
So(images[0].NewestImage.Tag, ShouldEqual, "0.0.1")
|
||||
So(images[0].NewestImage.Vulnerabilities.Count, ShouldEqual, 0)
|
||||
So(images[0].NewestImage.Vulnerabilities.UnknownCount, ShouldEqual, 0)
|
||||
So(images[0].NewestImage.Vulnerabilities.LowCount, ShouldEqual, 0)
|
||||
So(images[0].NewestImage.Vulnerabilities.MediumCount, ShouldEqual, 0)
|
||||
So(images[0].NewestImage.Vulnerabilities.HighCount, ShouldEqual, 0)
|
||||
So(images[0].NewestImage.Vulnerabilities.CriticalCount, ShouldEqual, 0)
|
||||
So(images[0].NewestImage.Vulnerabilities.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
query = `{
|
||||
@ -741,6 +750,11 @@ func TestRepoListWithNewestImage(t *testing.T) {
|
||||
Digest
|
||||
Vulnerabilities{
|
||||
MaxSeverity
|
||||
UnknownCount
|
||||
LowCount
|
||||
MediumCount
|
||||
HighCount
|
||||
CriticalCount
|
||||
Count
|
||||
}
|
||||
}
|
||||
@ -765,12 +779,12 @@ func TestRepoListWithNewestImage(t *testing.T) {
|
||||
So(vulnerabilities, ShouldNotBeNil)
|
||||
t.Logf("Found vulnerability summary %v", vulnerabilities)
|
||||
// Depends on test data, but current tested images contain hundreds
|
||||
So(vulnerabilities.Count, ShouldBeGreaterThan, 1)
|
||||
So(
|
||||
dbTypes.CompareSeverityString(dbTypes.SeverityUnknown.String(), vulnerabilities.MaxSeverity),
|
||||
ShouldBeGreaterThan,
|
||||
0,
|
||||
)
|
||||
So(vulnerabilities.Count, ShouldEqual, 4)
|
||||
So(vulnerabilities.UnknownCount, ShouldEqual, 0)
|
||||
So(vulnerabilities.LowCount, ShouldEqual, 1)
|
||||
So(vulnerabilities.MediumCount, ShouldEqual, 1)
|
||||
So(vulnerabilities.HighCount, ShouldEqual, 1)
|
||||
So(vulnerabilities.CriticalCount, ShouldEqual, 1)
|
||||
So(vulnerabilities.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
}
|
||||
})
|
||||
@ -3178,7 +3192,7 @@ func TestGlobalSearch(t *testing.T) {
|
||||
Layer { Size Digest }
|
||||
HistoryDescription { Author Comment Created CreatedBy EmptyLayer }
|
||||
}
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
}
|
||||
Vendor
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
@ -3199,7 +3213,7 @@ func TestGlobalSearch(t *testing.T) {
|
||||
HistoryDescription { Author Comment Created CreatedBy EmptyLayer }
|
||||
}
|
||||
}
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
}
|
||||
}
|
||||
Layers { Digest Size }
|
||||
@ -3256,6 +3270,11 @@ func TestGlobalSearch(t *testing.T) {
|
||||
// No vulnerabilities should be detected since trivy is disabled
|
||||
t.Logf("Found vulnerability summary %v", repoSummary.NewestImage.Vulnerabilities)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.Count, ShouldEqual, 0)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.UnknownCount, ShouldEqual, 0)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.LowCount, ShouldEqual, 0)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.MediumCount, ShouldEqual, 0)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.HighCount, ShouldEqual, 0)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.CriticalCount, ShouldEqual, 0)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.MaxSeverity, ShouldEqual, "")
|
||||
}
|
||||
|
||||
@ -3272,7 +3291,7 @@ func TestGlobalSearch(t *testing.T) {
|
||||
HistoryDescription { Author Comment Created CreatedBy EmptyLayer }
|
||||
}
|
||||
}
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
}
|
||||
Repos {
|
||||
Name LastUpdated Size
|
||||
@ -3288,7 +3307,7 @@ func TestGlobalSearch(t *testing.T) {
|
||||
HistoryDescription { Author Comment Created CreatedBy EmptyLayer }
|
||||
}
|
||||
}
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
}
|
||||
}
|
||||
Layers { Digest Size }
|
||||
@ -3323,6 +3342,11 @@ func TestGlobalSearch(t *testing.T) {
|
||||
// 0 vulnerabilities should be detected since trivy is disabled
|
||||
t.Logf("Found vulnerability summary %v", actualImageSummary.Vulnerabilities)
|
||||
So(actualImageSummary.Vulnerabilities.Count, ShouldEqual, 0)
|
||||
So(actualImageSummary.Vulnerabilities.UnknownCount, ShouldEqual, 0)
|
||||
So(actualImageSummary.Vulnerabilities.LowCount, ShouldEqual, 0)
|
||||
So(actualImageSummary.Vulnerabilities.MediumCount, ShouldEqual, 0)
|
||||
So(actualImageSummary.Vulnerabilities.HighCount, ShouldEqual, 0)
|
||||
So(actualImageSummary.Vulnerabilities.CriticalCount, ShouldEqual, 0)
|
||||
So(actualImageSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "")
|
||||
})
|
||||
|
||||
@ -3500,7 +3524,7 @@ func TestGlobalSearch(t *testing.T) {
|
||||
HistoryDescription { Author Comment Created CreatedBy EmptyLayer }
|
||||
}
|
||||
}
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
}
|
||||
Repos {
|
||||
Name LastUpdated Size
|
||||
@ -3516,7 +3540,7 @@ func TestGlobalSearch(t *testing.T) {
|
||||
HistoryDescription { Author Comment Created CreatedBy EmptyLayer }
|
||||
}
|
||||
}
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
}
|
||||
}
|
||||
Layers { Digest Size }
|
||||
@ -3575,10 +3599,20 @@ func TestGlobalSearch(t *testing.T) {
|
||||
if repoName == "repo1" { //nolint:goconst
|
||||
So(repoSummary.NewestImage.Vulnerabilities.Count, ShouldEqual, 4)
|
||||
// There are 4 vulnerabilities in the data used in tests
|
||||
So(repoSummary.NewestImage.Vulnerabilities.UnknownCount, ShouldEqual, 0)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.LowCount, ShouldEqual, 1)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.MediumCount, ShouldEqual, 1)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.HighCount, ShouldEqual, 1)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.CriticalCount, ShouldEqual, 1)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
} else {
|
||||
So(repoSummary.NewestImage.Vulnerabilities.Count, ShouldEqual, 0)
|
||||
// There are 0 vulnerabilities this data used in tests
|
||||
So(repoSummary.NewestImage.Vulnerabilities.UnknownCount, ShouldEqual, 0)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.LowCount, ShouldEqual, 0)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.MediumCount, ShouldEqual, 0)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.HighCount, ShouldEqual, 0)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.CriticalCount, ShouldEqual, 0)
|
||||
So(repoSummary.NewestImage.Vulnerabilities.MaxSeverity, ShouldEqual, "NONE")
|
||||
}
|
||||
}
|
||||
@ -3596,7 +3630,7 @@ func TestGlobalSearch(t *testing.T) {
|
||||
HistoryDescription { Author Comment Created CreatedBy EmptyLayer }
|
||||
}
|
||||
}
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
}
|
||||
Repos {
|
||||
Name LastUpdated Size
|
||||
@ -3612,7 +3646,7 @@ func TestGlobalSearch(t *testing.T) {
|
||||
HistoryDescription { Author Comment Created CreatedBy EmptyLayer }
|
||||
}
|
||||
}
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
}
|
||||
}
|
||||
Layers { Digest Size }
|
||||
@ -3647,6 +3681,11 @@ func TestGlobalSearch(t *testing.T) {
|
||||
t.Logf("Found vulnerability summary %v", actualImageSummary.Vulnerabilities)
|
||||
// There are 4 vulnerabilities in the data used in tests
|
||||
So(actualImageSummary.Vulnerabilities.Count, ShouldEqual, 4)
|
||||
So(actualImageSummary.Vulnerabilities.UnknownCount, ShouldEqual, 0)
|
||||
So(actualImageSummary.Vulnerabilities.LowCount, ShouldEqual, 1)
|
||||
So(actualImageSummary.Vulnerabilities.MediumCount, ShouldEqual, 1)
|
||||
So(actualImageSummary.Vulnerabilities.HighCount, ShouldEqual, 1)
|
||||
So(actualImageSummary.Vulnerabilities.CriticalCount, ShouldEqual, 1)
|
||||
So(actualImageSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
})
|
||||
|
||||
@ -5949,7 +5988,7 @@ func TestImageSummary(t *testing.T) {
|
||||
Size
|
||||
Platform { Os Arch }
|
||||
Layers { Digest Size }
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
History {
|
||||
HistoryDescription { Created }
|
||||
Layer { Digest Size }
|
||||
@ -5957,7 +5996,7 @@ func TestImageSummary(t *testing.T) {
|
||||
}
|
||||
LastUpdated
|
||||
Size
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
Referrers {MediaType ArtifactType Digest Annotations {Key Value}}
|
||||
}
|
||||
}`
|
||||
@ -5976,7 +6015,7 @@ func TestImageSummary(t *testing.T) {
|
||||
Size
|
||||
Platform { Os Arch }
|
||||
Layers { Digest Size }
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
History {
|
||||
HistoryDescription { Created }
|
||||
Layer { Digest Size }
|
||||
@ -6089,6 +6128,11 @@ func TestImageSummary(t *testing.T) {
|
||||
So(imgSummary.Manifests[0].History[0].HistoryDescription.Created, ShouldEqual, createdTime)
|
||||
// No vulnerabilities should be detected since trivy is disabled
|
||||
So(imgSummary.Vulnerabilities.Count, ShouldEqual, 0)
|
||||
So(imgSummary.Vulnerabilities.UnknownCount, ShouldEqual, 0)
|
||||
So(imgSummary.Vulnerabilities.LowCount, ShouldEqual, 0)
|
||||
So(imgSummary.Vulnerabilities.MediumCount, ShouldEqual, 0)
|
||||
So(imgSummary.Vulnerabilities.HighCount, ShouldEqual, 0)
|
||||
So(imgSummary.Vulnerabilities.CriticalCount, ShouldEqual, 0)
|
||||
So(imgSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "")
|
||||
So(len(imgSummary.Referrers), ShouldEqual, 1)
|
||||
So(imgSummary.Referrers[0], ShouldResemble, zcommon.Referrer{
|
||||
@ -6177,7 +6221,7 @@ func TestImageSummary(t *testing.T) {
|
||||
Size
|
||||
Platform { Os Arch }
|
||||
Layers { Digest Size }
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
History {
|
||||
HistoryDescription { Created }
|
||||
Layer { Digest Size }
|
||||
@ -6185,7 +6229,7 @@ func TestImageSummary(t *testing.T) {
|
||||
}
|
||||
LastUpdated
|
||||
Size
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
}
|
||||
}`
|
||||
|
||||
@ -6271,6 +6315,11 @@ func TestImageSummary(t *testing.T) {
|
||||
So(len(imgSummary.Manifests[0].History), ShouldEqual, 1)
|
||||
So(imgSummary.Manifests[0].History[0].HistoryDescription.Created, ShouldEqual, createdTime)
|
||||
So(imgSummary.Vulnerabilities.Count, ShouldEqual, 4)
|
||||
So(imgSummary.Vulnerabilities.UnknownCount, ShouldEqual, 0)
|
||||
So(imgSummary.Vulnerabilities.LowCount, ShouldEqual, 1)
|
||||
So(imgSummary.Vulnerabilities.MediumCount, ShouldEqual, 1)
|
||||
So(imgSummary.Vulnerabilities.HighCount, ShouldEqual, 1)
|
||||
So(imgSummary.Vulnerabilities.CriticalCount, ShouldEqual, 1)
|
||||
// There are 0 vulnerabilities this data used in tests
|
||||
So(imgSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
})
|
||||
@ -6800,11 +6849,11 @@ func GlobalSearchGQL(query, baseURL string) *zcommon.GlobalSearchResultResp {
|
||||
Layer { Size Digest }
|
||||
HistoryDescription { Author Comment Created CreatedBy EmptyLayer }
|
||||
}
|
||||
Vulnerabilities {Count MaxSeverity}
|
||||
Vulnerabilities {Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity}
|
||||
Referrers {MediaType ArtifactType Size Digest Annotations {Key Value}}
|
||||
}
|
||||
Referrers {MediaType ArtifactType Size Digest Annotations {Key Value}}
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
SignatureInfo {Tool IsTrusted Author}
|
||||
}
|
||||
Repos {
|
||||
@ -6824,11 +6873,11 @@ func GlobalSearchGQL(query, baseURL string) *zcommon.GlobalSearchResultResp {
|
||||
Layer { Size Digest }
|
||||
HistoryDescription { Author Comment Created CreatedBy EmptyLayer }
|
||||
}
|
||||
Vulnerabilities {Count MaxSeverity}
|
||||
Vulnerabilities {Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity}
|
||||
Referrers {MediaType ArtifactType Size Digest Annotations {Key Value}}
|
||||
}
|
||||
Referrers {MediaType ArtifactType Size Digest Annotations {Key Value}}
|
||||
Vulnerabilities { Count MaxSeverity }
|
||||
Vulnerabilities { Count UnknownCount LowCount MediumCount HighCount CriticalCount MaxSeverity }
|
||||
SignatureInfo {Tool IsTrusted Author}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ type CveInfoMock struct {
|
||||
GetImageListForCVEFn func(ctx context.Context, repo, cveID string) ([]cvemodel.TagInfo, error)
|
||||
GetImageListWithCVEFixedFn func(ctx context.Context, repo, cveID string) ([]cvemodel.TagInfo, error)
|
||||
GetCVEListForImageFn func(ctx context.Context, repo string, reference string, searchedCVE string,
|
||||
pageInput cvemodel.PageInput) ([]cvemodel.CVE, common.PageInfo, error)
|
||||
pageInput cvemodel.PageInput) ([]cvemodel.CVE, cvemodel.ImageCVESummary, common.PageInfo, error)
|
||||
GetCVESummaryForImageMediaFn func(ctx context.Context, repo string, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error)
|
||||
}
|
||||
@ -37,6 +37,7 @@ func (cveInfo CveInfoMock) GetCVEListForImage(ctx context.Context, repo string,
|
||||
searchedCVE string, pageInput cvemodel.PageInput,
|
||||
) (
|
||||
[]cvemodel.CVE,
|
||||
cvemodel.ImageCVESummary,
|
||||
common.PageInfo,
|
||||
error,
|
||||
) {
|
||||
@ -44,7 +45,7 @@ func (cveInfo CveInfoMock) GetCVEListForImage(ctx context.Context, repo string,
|
||||
return cveInfo.GetCVEListForImageFn(ctx, repo, reference, searchedCVE, pageInput)
|
||||
}
|
||||
|
||||
return []cvemodel.CVE{}, common.PageInfo{}, nil
|
||||
return []cvemodel.CVE{}, cvemodel.ImageCVESummary{}, common.PageInfo{}, nil
|
||||
}
|
||||
|
||||
func (cveInfo CveInfoMock) GetCVESummaryForImageMedia(ctx context.Context, repo, digest, mediaType string,
|
||||
|
Loading…
Reference in New Issue
Block a user