mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 12:28:01 +08:00
perf: update the ImageList queries to return PaginatedImagesResult (#1182)
Signed-off-by: Nicol Draghici <idraghic@cisco.com>
This commit is contained in:
@@ -81,14 +81,14 @@ type ImageListResponse struct {
|
||||
}
|
||||
|
||||
type ImageList struct {
|
||||
SummaryList []common.ImageSummary `json:"imageList"`
|
||||
PaginatedImagesResult `json:"imageList"`
|
||||
}
|
||||
|
||||
type DerivedImageList struct {
|
||||
DerivedList []common.ImageSummary `json:"derivedImageList"`
|
||||
PaginatedImagesResult `json:"derivedImageList"`
|
||||
}
|
||||
type BaseImageList struct {
|
||||
BaseList []common.ImageSummary `json:"baseImageList"`
|
||||
PaginatedImagesResult `json:"baseImageList"`
|
||||
}
|
||||
|
||||
type ExpandedRepoInfoResp struct {
|
||||
@@ -3582,17 +3582,19 @@ func TestImageList(t *testing.T) {
|
||||
Convey("without pagination, valid response", func() {
|
||||
query := fmt.Sprintf(`{
|
||||
ImageList(repo:"%s"){
|
||||
History{
|
||||
HistoryDescription{
|
||||
Author
|
||||
Comment
|
||||
Created
|
||||
CreatedBy
|
||||
EmptyLayer
|
||||
},
|
||||
Layer{
|
||||
Digest
|
||||
Size
|
||||
Results{
|
||||
History{
|
||||
HistoryDescription{
|
||||
Author
|
||||
Comment
|
||||
Created
|
||||
CreatedBy
|
||||
EmptyLayer
|
||||
},
|
||||
Layer{
|
||||
Digest
|
||||
Size
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3607,25 +3609,27 @@ func TestImageList(t *testing.T) {
|
||||
err = json.Unmarshal(resp.Body(), &responseStruct)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(responseStruct.ImageList.SummaryList), ShouldEqual, len(tags))
|
||||
So(len(responseStruct.ImageList.SummaryList[0].History), ShouldEqual, len(imageConfigInfo.History))
|
||||
So(len(responseStruct.ImageList.Results), ShouldEqual, len(tags))
|
||||
So(len(responseStruct.ImageList.Results[0].History), ShouldEqual, len(imageConfigInfo.History))
|
||||
})
|
||||
|
||||
Convey("Pagination with valid params", func() {
|
||||
limit := 1
|
||||
query := fmt.Sprintf(`{
|
||||
ImageList(repo:"%s", requestedPage:{limit: %d, offset: 0, sortBy:RELEVANCE}){
|
||||
History{
|
||||
HistoryDescription{
|
||||
Author
|
||||
Comment
|
||||
Created
|
||||
CreatedBy
|
||||
EmptyLayer
|
||||
},
|
||||
Layer{
|
||||
Digest
|
||||
Size
|
||||
Results{
|
||||
History{
|
||||
HistoryDescription{
|
||||
Author
|
||||
Comment
|
||||
Created
|
||||
CreatedBy
|
||||
EmptyLayer
|
||||
},
|
||||
Layer{
|
||||
Digest
|
||||
Size
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3640,7 +3644,7 @@ func TestImageList(t *testing.T) {
|
||||
err = json.Unmarshal(resp.Body(), &responseStruct)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(responseStruct.ImageList.SummaryList), ShouldEqual, limit)
|
||||
So(len(responseStruct.ImageList.Results), ShouldEqual, limit)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -423,11 +423,11 @@ func TestCVESearchDisabled(t *testing.T) {
|
||||
So(string(resp.Body()), ShouldContainSubstring, "search: CVE search is disabled")
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListForCVE(id:\"CVE-201-20482\"){RepoName%20Tag}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListForCVE(id:\"CVE-201-20482\"){Results{RepoName%20Tag}}}")
|
||||
So(string(resp.Body()), ShouldContainSubstring, "search: CVE search is disabled")
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + "randomId" + "\",image:\"zot-test\"){RepoName%20LastUpdated}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + "randomId" + "\",image:\"zot-test\"){Results{RepoName%20LastUpdated}}}")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(string(resp.Body()), ShouldContainSubstring, "search: CVE search is disabled")
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
@@ -547,7 +547,7 @@ func TestCVESearch(t *testing.T) {
|
||||
|
||||
cvid := cveResult.ImgList.CVEResultForImage.CVEList[0].ID
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-test\"){RepoName%20LastUpdated}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-test\"){Results{RepoName%20LastUpdated}}}")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
@@ -556,7 +556,7 @@ func TestCVESearch(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
So(len(imgListWithCVEFixed.Images), ShouldEqual, 0)
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-cve-test\"){RepoName%20LastUpdated}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-cve-test\"){Results{RepoName%20LastUpdated}}}")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
@@ -564,7 +564,7 @@ func TestCVESearch(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
So(len(imgListWithCVEFixed.Images), ShouldEqual, 0)
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-test\"){RepoName%20LastUpdated}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-test\"){Results{RepoName%20LastUpdated}}}")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
@@ -581,7 +581,7 @@ func TestCVESearch(t *testing.T) {
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-squashfs-noindex\"){RepoName%20LastUpdated}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-squashfs-noindex\"){Results{RepoName%20LastUpdated}}}")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
@@ -589,7 +589,7 @@ func TestCVESearch(t *testing.T) {
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-squashfs-invalid-index\"){RepoName%20LastUpdated}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-squashfs-invalid-index\"){Results{RepoName%20LastUpdated}}}")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
@@ -597,11 +597,11 @@ func TestCVESearch(t *testing.T) {
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-squashfs-noblob\"){RepoName%20LastUpdated}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-squashfs-noblob\"){Results{RepoName%20LastUpdated}}}")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-squashfs-test\"){RepoName%20LastUpdated}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-squashfs-test\"){Results{RepoName%20LastUpdated}}}")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
@@ -609,7 +609,7 @@ func TestCVESearch(t *testing.T) {
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-squashfs-invalid-blob\"){RepoName%20LastUpdated}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListWithCVEFixed(id:\"" + cvid + "\",image:\"zot-squashfs-invalid-blob\"){Results{RepoName%20LastUpdated}}}")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
@@ -621,7 +621,7 @@ func TestCVESearch(t *testing.T) {
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListForCVE(id:\"CVE-201-20482\"){RepoName%20Tag}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListForCVE(id:\"CVE-201-20482\"){Results{RepoName%20Tag}}}")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
@@ -662,11 +662,11 @@ func TestCVESearch(t *testing.T) {
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 422)
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListForCVE(tet:\"CVE-2018-20482\"){RepoName%20Tag}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListForCVE(tet:\"CVE-2018-20482\"){Results{RepoName%20Tag}}}")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 422)
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageistForCVE(id:\"CVE-2018-20482\"){RepoName%20Tag}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageistForCVE(id:\"CVE-2018-20482\"){Results{RepoName%20Tag}}}")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 422)
|
||||
|
||||
@@ -678,7 +678,7 @@ func TestCVESearch(t *testing.T) {
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 422)
|
||||
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListForCVE(id:\"" + cvid + "\"){RepoName%20Tag}}")
|
||||
resp, _ = resty.R().SetBasicAuth(username, passphrase).Get(baseURL + constants.FullSearchPrefix + "?query={ImageListForCVE(id:\"" + cvid + "\"){Results{RepoName%20Tag}}}")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
})
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"zotregistry.io/zot/pkg/extensions/monitoring"
|
||||
digestinfo "zotregistry.io/zot/pkg/extensions/search/digest"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/meta/repodb"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
"zotregistry.io/zot/pkg/storage/local"
|
||||
. "zotregistry.io/zot/pkg/test"
|
||||
@@ -32,7 +33,7 @@ type ImgResponseForDigest struct {
|
||||
|
||||
//nolint:tagliatelle // graphQL schema
|
||||
type ImgListForDigest struct {
|
||||
Images []ImgInfo `json:"ImageListForDigest"`
|
||||
PaginatedImagesResult `json:"ImageListForDigest"`
|
||||
}
|
||||
|
||||
//nolint:tagliatelle // graphQL schema
|
||||
@@ -49,6 +50,11 @@ type ErrorGQL struct {
|
||||
Path []string `json:"path"`
|
||||
}
|
||||
|
||||
type PaginatedImagesResult struct {
|
||||
Results []ImgInfo `json:"results"`
|
||||
Page repodb.PageInfo `json:"page"`
|
||||
}
|
||||
|
||||
func testSetup(t *testing.T) (string, string, *digestinfo.DigestInfo) {
|
||||
t.Helper()
|
||||
dir := t.TempDir()
|
||||
@@ -155,7 +161,7 @@ func TestDigestSearchHTTP(t *testing.T) {
|
||||
// "sha" should match all digests in all images
|
||||
resp, err = resty.R().Get(
|
||||
baseURL + constants.FullSearchPrefix + `?query={ImageListForDigest(id:"sha")` +
|
||||
`{RepoName%20Tag%20Digest%20ConfigDigest%20Size%20Layers%20{%20Digest}}}`,
|
||||
`{Results{RepoName%20Tag%20Digest%20ConfigDigest%20Size%20Layers%20{%20Digest}}}}`,
|
||||
)
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(err, ShouldBeNil)
|
||||
@@ -165,14 +171,14 @@ func TestDigestSearchHTTP(t *testing.T) {
|
||||
err = json.Unmarshal(resp.Body(), &responseStruct)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(responseStruct.Errors), ShouldEqual, 0)
|
||||
So(len(responseStruct.ImgListForDigest.Images), ShouldEqual, 2)
|
||||
So(responseStruct.ImgListForDigest.Images[0].Tag, ShouldEqual, "0.0.1")
|
||||
So(len(responseStruct.ImgListForDigest.Results), ShouldEqual, 2)
|
||||
So(responseStruct.ImgListForDigest.Results[0].Tag, ShouldEqual, "0.0.1")
|
||||
|
||||
// Call should return {"data":{"ImageListForDigest":[{"Name":"zot-test","Tags":["0.0.1"]}]}}
|
||||
// GetTestBlobDigest("zot-test", "manifest").Encoded() should match the manifest of 1 image
|
||||
|
||||
gqlQuery := url.QueryEscape(`{ImageListForDigest(id:"` + GetTestBlobDigest("zot-test", "manifest").Encoded() + `")
|
||||
{RepoName Tag Digest ConfigDigest Size Layers { Digest }}}`)
|
||||
{Results{RepoName Tag Digest ConfigDigest Size Layers { Digest }}}}`)
|
||||
targetURL := baseURL + constants.FullSearchPrefix + `?query=` + gqlQuery
|
||||
|
||||
resp, err = resty.R().Get(targetURL)
|
||||
@@ -184,13 +190,13 @@ func TestDigestSearchHTTP(t *testing.T) {
|
||||
err = json.Unmarshal(resp.Body(), &responseStruct)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(responseStruct.Errors), ShouldEqual, 0)
|
||||
So(len(responseStruct.ImgListForDigest.Images), ShouldEqual, 1)
|
||||
So(responseStruct.ImgListForDigest.Images[0].RepoName, ShouldEqual, "zot-test")
|
||||
So(responseStruct.ImgListForDigest.Images[0].Tag, ShouldEqual, "0.0.1")
|
||||
So(len(responseStruct.ImgListForDigest.Results), ShouldEqual, 1)
|
||||
So(responseStruct.ImgListForDigest.Results[0].RepoName, ShouldEqual, "zot-test")
|
||||
So(responseStruct.ImgListForDigest.Results[0].Tag, ShouldEqual, "0.0.1")
|
||||
|
||||
// GetTestBlobDigest("zot-test", "config").Encoded() should match the config of 1 image.
|
||||
gqlQuery = url.QueryEscape(`{ImageListForDigest(id:"` + GetTestBlobDigest("zot-test", "config").Encoded() + `")
|
||||
{RepoName Tag Digest ConfigDigest Size Layers { Digest }}}`)
|
||||
{Results{RepoName Tag Digest ConfigDigest Size Layers { Digest }}}}`)
|
||||
|
||||
targetURL = baseURL + constants.FullSearchPrefix + `?query=` + gqlQuery
|
||||
resp, err = resty.R().Get(targetURL)
|
||||
@@ -202,14 +208,14 @@ func TestDigestSearchHTTP(t *testing.T) {
|
||||
err = json.Unmarshal(resp.Body(), &responseStruct)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(responseStruct.Errors), ShouldEqual, 0)
|
||||
So(len(responseStruct.ImgListForDigest.Images), ShouldEqual, 1)
|
||||
So(responseStruct.ImgListForDigest.Images[0].RepoName, ShouldEqual, "zot-test")
|
||||
So(responseStruct.ImgListForDigest.Images[0].Tag, ShouldEqual, "0.0.1")
|
||||
So(len(responseStruct.ImgListForDigest.Results), ShouldEqual, 1)
|
||||
So(responseStruct.ImgListForDigest.Results[0].RepoName, ShouldEqual, "zot-test")
|
||||
So(responseStruct.ImgListForDigest.Results[0].Tag, ShouldEqual, "0.0.1")
|
||||
|
||||
// Call should return {"data":{"ImageListForDigest":[{"Name":"zot-cve-test","Tags":["0.0.1"]}]}}
|
||||
// GetTestBlobDigest("zot-cve-test", "layer").Encoded() should match the layer of 1 image
|
||||
gqlQuery = url.QueryEscape(`{ImageListForDigest(id:"` + GetTestBlobDigest("zot-cve-test", "layer").Encoded() + `")
|
||||
{RepoName Tag Digest ConfigDigest Size Layers { Digest }}}`)
|
||||
{Results{RepoName Tag Digest ConfigDigest Size Layers { Digest }}}}`)
|
||||
targetURL = baseURL + constants.FullSearchPrefix + `?query=` + gqlQuery
|
||||
|
||||
resp, err = resty.R().Get(
|
||||
@@ -224,15 +230,15 @@ func TestDigestSearchHTTP(t *testing.T) {
|
||||
err = json.Unmarshal(resp.Body(), &responseStruct2)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(responseStruct2.Errors), ShouldEqual, 0)
|
||||
So(len(responseStruct2.ImgListForDigest.Images), ShouldEqual, 1)
|
||||
So(responseStruct2.ImgListForDigest.Images[0].RepoName, ShouldEqual, "zot-cve-test")
|
||||
So(responseStruct2.ImgListForDigest.Images[0].Tag, ShouldEqual, "0.0.1")
|
||||
So(len(responseStruct2.ImgListForDigest.Results), ShouldEqual, 1)
|
||||
So(responseStruct2.ImgListForDigest.Results[0].RepoName, ShouldEqual, "zot-cve-test")
|
||||
So(responseStruct2.ImgListForDigest.Results[0].Tag, ShouldEqual, "0.0.1")
|
||||
|
||||
// Call should return {"data":{"ImageListForDigest":[]}}
|
||||
// "1111111" should match 0 images
|
||||
resp, err = resty.R().Get(
|
||||
baseURL + constants.FullSearchPrefix + `?query={ImageListForDigest(id:"1111111")` +
|
||||
`{RepoName%20Tag%20Digest%20ConfigDigest%20Size%20Layers%20{%20Digest}}}`,
|
||||
`{Results{RepoName%20Tag%20Digest%20ConfigDigest%20Size%20Layers%20{%20Digest}}}}`,
|
||||
)
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(err, ShouldBeNil)
|
||||
@@ -241,12 +247,12 @@ func TestDigestSearchHTTP(t *testing.T) {
|
||||
err = json.Unmarshal(resp.Body(), &responseStruct)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(responseStruct.Errors), ShouldEqual, 0)
|
||||
So(len(responseStruct.ImgListForDigest.Images), ShouldEqual, 0)
|
||||
So(len(responseStruct.ImgListForDigest.Results), ShouldEqual, 0)
|
||||
|
||||
// Call should return {"errors": [{....}]", data":null}}
|
||||
resp, err = resty.R().Get(
|
||||
baseURL + constants.FullSearchPrefix + `?query={ImageListForDigest(id:"1111111")` +
|
||||
`{RepoName%20Tag343s}}`,
|
||||
`{Results{RepoName%20Tag343s}}}`,
|
||||
)
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(err, ShouldBeNil)
|
||||
@@ -302,7 +308,7 @@ func TestDigestSearchHTTPSubPaths(t *testing.T) {
|
||||
|
||||
resp, err = resty.R().Get(
|
||||
baseURL + constants.FullSearchPrefix + `?query={ImageListForDigest(id:"sha")` +
|
||||
`{RepoName%20Tag%20Digest%20ConfigDigest%20Size%20Layers%20{%20Digest}}}`,
|
||||
`{Results{RepoName%20Tag%20Digest%20ConfigDigest%20Size%20Layers%20{%20Digest}}}}`,
|
||||
)
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(err, ShouldBeNil)
|
||||
@@ -312,7 +318,7 @@ func TestDigestSearchHTTPSubPaths(t *testing.T) {
|
||||
err = json.Unmarshal(resp.Body(), &responseStruct)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(responseStruct.Errors), ShouldEqual, 0)
|
||||
So(len(responseStruct.ImgListForDigest.Images), ShouldEqual, 2)
|
||||
So(len(responseStruct.ImgListForDigest.Results), ShouldEqual, 2)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -188,11 +188,11 @@ type ComplexityRoot struct {
|
||||
|
||||
type QueryResolver interface {
|
||||
CVEListForImage(ctx context.Context, image string, requestedPage *PageInput) (*CVEResultForImage, error)
|
||||
ImageListForCve(ctx context.Context, id string, requestedPage *PageInput) ([]*ImageSummary, error)
|
||||
ImageListWithCVEFixed(ctx context.Context, id string, image string, requestedPage *PageInput) ([]*ImageSummary, error)
|
||||
ImageListForDigest(ctx context.Context, id string, requestedPage *PageInput) ([]*ImageSummary, error)
|
||||
ImageListForCve(ctx context.Context, id string, requestedPage *PageInput) (*PaginatedImagesResult, error)
|
||||
ImageListWithCVEFixed(ctx context.Context, id string, image string, requestedPage *PageInput) (*PaginatedImagesResult, error)
|
||||
ImageListForDigest(ctx context.Context, id string, requestedPage *PageInput) (*PaginatedImagesResult, error)
|
||||
RepoListWithNewestImage(ctx context.Context, requestedPage *PageInput) (*PaginatedReposResult, error)
|
||||
ImageList(ctx context.Context, repo string, requestedPage *PageInput) ([]*ImageSummary, error)
|
||||
ImageList(ctx context.Context, repo string, requestedPage *PageInput) (*PaginatedImagesResult, error)
|
||||
ExpandedRepoInfo(ctx context.Context, repo string) (*RepoInfo, error)
|
||||
GlobalSearch(ctx context.Context, query string, filter *Filter, requestedPage *PageInput) (*GlobalSearchResult, error)
|
||||
DerivedImageList(ctx context.Context, image string, requestedPage *PageInput) (*PaginatedImagesResult, error)
|
||||
@@ -1483,7 +1483,7 @@ type Query {
|
||||
id: String!,
|
||||
"Sets the parameters of the requested page"
|
||||
requestedPage: PageInput
|
||||
): [ImageSummary!]
|
||||
): PaginatedImagesResult!
|
||||
|
||||
"""
|
||||
Returns a list of images that are no longer vulnerable to the CVE of the specified ID,
|
||||
@@ -1496,7 +1496,7 @@ type Query {
|
||||
image: String!,
|
||||
"Sets the parameters of the requested page"
|
||||
requestedPage: PageInput
|
||||
): [ImageSummary!]
|
||||
): PaginatedImagesResult!
|
||||
|
||||
"""
|
||||
Returns a list of images which contain the specified digest
|
||||
@@ -1506,7 +1506,7 @@ type Query {
|
||||
id: String!,
|
||||
"Sets the parameters of the requested page"
|
||||
requestedPage: PageInput
|
||||
): [ImageSummary!]
|
||||
): PaginatedImagesResult!
|
||||
|
||||
"""
|
||||
Returns a list of repositories with the newest tag (most recently created timestamp)
|
||||
@@ -1524,7 +1524,7 @@ type Query {
|
||||
repo: String!,
|
||||
"Sets the parameters of the requested page"
|
||||
requestedPage: PageInput
|
||||
): [ImageSummary!]
|
||||
): PaginatedImagesResult!
|
||||
|
||||
"""
|
||||
Obtain detailed information about a repository and container images within
|
||||
@@ -4647,11 +4647,14 @@ func (ec *executionContext) _Query_ImageListForCVE(ctx context.Context, field gr
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.([]*ImageSummary)
|
||||
res := resTmp.(*PaginatedImagesResult)
|
||||
fc.Result = res
|
||||
return ec.marshalOImageSummary2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐImageSummaryᚄ(ctx, field.Selections, res)
|
||||
return ec.marshalNPaginatedImagesResult2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐPaginatedImagesResult(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Query_ImageListForCVE(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
@@ -4662,50 +4665,12 @@ func (ec *executionContext) fieldContext_Query_ImageListForCVE(ctx context.Conte
|
||||
IsResolver: true,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
switch field.Name {
|
||||
case "RepoName":
|
||||
return ec.fieldContext_ImageSummary_RepoName(ctx, field)
|
||||
case "Tag":
|
||||
return ec.fieldContext_ImageSummary_Tag(ctx, field)
|
||||
case "Digest":
|
||||
return ec.fieldContext_ImageSummary_Digest(ctx, field)
|
||||
case "ConfigDigest":
|
||||
return ec.fieldContext_ImageSummary_ConfigDigest(ctx, field)
|
||||
case "LastUpdated":
|
||||
return ec.fieldContext_ImageSummary_LastUpdated(ctx, field)
|
||||
case "IsSigned":
|
||||
return ec.fieldContext_ImageSummary_IsSigned(ctx, field)
|
||||
case "Size":
|
||||
return ec.fieldContext_ImageSummary_Size(ctx, field)
|
||||
case "Platform":
|
||||
return ec.fieldContext_ImageSummary_Platform(ctx, field)
|
||||
case "Vendor":
|
||||
return ec.fieldContext_ImageSummary_Vendor(ctx, field)
|
||||
case "Score":
|
||||
return ec.fieldContext_ImageSummary_Score(ctx, field)
|
||||
case "DownloadCount":
|
||||
return ec.fieldContext_ImageSummary_DownloadCount(ctx, field)
|
||||
case "Layers":
|
||||
return ec.fieldContext_ImageSummary_Layers(ctx, field)
|
||||
case "Description":
|
||||
return ec.fieldContext_ImageSummary_Description(ctx, field)
|
||||
case "Licenses":
|
||||
return ec.fieldContext_ImageSummary_Licenses(ctx, field)
|
||||
case "Labels":
|
||||
return ec.fieldContext_ImageSummary_Labels(ctx, field)
|
||||
case "Title":
|
||||
return ec.fieldContext_ImageSummary_Title(ctx, field)
|
||||
case "Source":
|
||||
return ec.fieldContext_ImageSummary_Source(ctx, field)
|
||||
case "Documentation":
|
||||
return ec.fieldContext_ImageSummary_Documentation(ctx, field)
|
||||
case "History":
|
||||
return ec.fieldContext_ImageSummary_History(ctx, field)
|
||||
case "Vulnerabilities":
|
||||
return ec.fieldContext_ImageSummary_Vulnerabilities(ctx, field)
|
||||
case "Authors":
|
||||
return ec.fieldContext_ImageSummary_Authors(ctx, field)
|
||||
case "Page":
|
||||
return ec.fieldContext_PaginatedImagesResult_Page(ctx, field)
|
||||
case "Results":
|
||||
return ec.fieldContext_PaginatedImagesResult_Results(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
|
||||
return nil, fmt.Errorf("no field named %q was found under type PaginatedImagesResult", field.Name)
|
||||
},
|
||||
}
|
||||
defer func() {
|
||||
@@ -4743,11 +4708,14 @@ func (ec *executionContext) _Query_ImageListWithCVEFixed(ctx context.Context, fi
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.([]*ImageSummary)
|
||||
res := resTmp.(*PaginatedImagesResult)
|
||||
fc.Result = res
|
||||
return ec.marshalOImageSummary2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐImageSummaryᚄ(ctx, field.Selections, res)
|
||||
return ec.marshalNPaginatedImagesResult2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐPaginatedImagesResult(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Query_ImageListWithCVEFixed(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
@@ -4758,50 +4726,12 @@ func (ec *executionContext) fieldContext_Query_ImageListWithCVEFixed(ctx context
|
||||
IsResolver: true,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
switch field.Name {
|
||||
case "RepoName":
|
||||
return ec.fieldContext_ImageSummary_RepoName(ctx, field)
|
||||
case "Tag":
|
||||
return ec.fieldContext_ImageSummary_Tag(ctx, field)
|
||||
case "Digest":
|
||||
return ec.fieldContext_ImageSummary_Digest(ctx, field)
|
||||
case "ConfigDigest":
|
||||
return ec.fieldContext_ImageSummary_ConfigDigest(ctx, field)
|
||||
case "LastUpdated":
|
||||
return ec.fieldContext_ImageSummary_LastUpdated(ctx, field)
|
||||
case "IsSigned":
|
||||
return ec.fieldContext_ImageSummary_IsSigned(ctx, field)
|
||||
case "Size":
|
||||
return ec.fieldContext_ImageSummary_Size(ctx, field)
|
||||
case "Platform":
|
||||
return ec.fieldContext_ImageSummary_Platform(ctx, field)
|
||||
case "Vendor":
|
||||
return ec.fieldContext_ImageSummary_Vendor(ctx, field)
|
||||
case "Score":
|
||||
return ec.fieldContext_ImageSummary_Score(ctx, field)
|
||||
case "DownloadCount":
|
||||
return ec.fieldContext_ImageSummary_DownloadCount(ctx, field)
|
||||
case "Layers":
|
||||
return ec.fieldContext_ImageSummary_Layers(ctx, field)
|
||||
case "Description":
|
||||
return ec.fieldContext_ImageSummary_Description(ctx, field)
|
||||
case "Licenses":
|
||||
return ec.fieldContext_ImageSummary_Licenses(ctx, field)
|
||||
case "Labels":
|
||||
return ec.fieldContext_ImageSummary_Labels(ctx, field)
|
||||
case "Title":
|
||||
return ec.fieldContext_ImageSummary_Title(ctx, field)
|
||||
case "Source":
|
||||
return ec.fieldContext_ImageSummary_Source(ctx, field)
|
||||
case "Documentation":
|
||||
return ec.fieldContext_ImageSummary_Documentation(ctx, field)
|
||||
case "History":
|
||||
return ec.fieldContext_ImageSummary_History(ctx, field)
|
||||
case "Vulnerabilities":
|
||||
return ec.fieldContext_ImageSummary_Vulnerabilities(ctx, field)
|
||||
case "Authors":
|
||||
return ec.fieldContext_ImageSummary_Authors(ctx, field)
|
||||
case "Page":
|
||||
return ec.fieldContext_PaginatedImagesResult_Page(ctx, field)
|
||||
case "Results":
|
||||
return ec.fieldContext_PaginatedImagesResult_Results(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
|
||||
return nil, fmt.Errorf("no field named %q was found under type PaginatedImagesResult", field.Name)
|
||||
},
|
||||
}
|
||||
defer func() {
|
||||
@@ -4839,11 +4769,14 @@ func (ec *executionContext) _Query_ImageListForDigest(ctx context.Context, field
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.([]*ImageSummary)
|
||||
res := resTmp.(*PaginatedImagesResult)
|
||||
fc.Result = res
|
||||
return ec.marshalOImageSummary2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐImageSummaryᚄ(ctx, field.Selections, res)
|
||||
return ec.marshalNPaginatedImagesResult2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐPaginatedImagesResult(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Query_ImageListForDigest(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
@@ -4854,50 +4787,12 @@ func (ec *executionContext) fieldContext_Query_ImageListForDigest(ctx context.Co
|
||||
IsResolver: true,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
switch field.Name {
|
||||
case "RepoName":
|
||||
return ec.fieldContext_ImageSummary_RepoName(ctx, field)
|
||||
case "Tag":
|
||||
return ec.fieldContext_ImageSummary_Tag(ctx, field)
|
||||
case "Digest":
|
||||
return ec.fieldContext_ImageSummary_Digest(ctx, field)
|
||||
case "ConfigDigest":
|
||||
return ec.fieldContext_ImageSummary_ConfigDigest(ctx, field)
|
||||
case "LastUpdated":
|
||||
return ec.fieldContext_ImageSummary_LastUpdated(ctx, field)
|
||||
case "IsSigned":
|
||||
return ec.fieldContext_ImageSummary_IsSigned(ctx, field)
|
||||
case "Size":
|
||||
return ec.fieldContext_ImageSummary_Size(ctx, field)
|
||||
case "Platform":
|
||||
return ec.fieldContext_ImageSummary_Platform(ctx, field)
|
||||
case "Vendor":
|
||||
return ec.fieldContext_ImageSummary_Vendor(ctx, field)
|
||||
case "Score":
|
||||
return ec.fieldContext_ImageSummary_Score(ctx, field)
|
||||
case "DownloadCount":
|
||||
return ec.fieldContext_ImageSummary_DownloadCount(ctx, field)
|
||||
case "Layers":
|
||||
return ec.fieldContext_ImageSummary_Layers(ctx, field)
|
||||
case "Description":
|
||||
return ec.fieldContext_ImageSummary_Description(ctx, field)
|
||||
case "Licenses":
|
||||
return ec.fieldContext_ImageSummary_Licenses(ctx, field)
|
||||
case "Labels":
|
||||
return ec.fieldContext_ImageSummary_Labels(ctx, field)
|
||||
case "Title":
|
||||
return ec.fieldContext_ImageSummary_Title(ctx, field)
|
||||
case "Source":
|
||||
return ec.fieldContext_ImageSummary_Source(ctx, field)
|
||||
case "Documentation":
|
||||
return ec.fieldContext_ImageSummary_Documentation(ctx, field)
|
||||
case "History":
|
||||
return ec.fieldContext_ImageSummary_History(ctx, field)
|
||||
case "Vulnerabilities":
|
||||
return ec.fieldContext_ImageSummary_Vulnerabilities(ctx, field)
|
||||
case "Authors":
|
||||
return ec.fieldContext_ImageSummary_Authors(ctx, field)
|
||||
case "Page":
|
||||
return ec.fieldContext_PaginatedImagesResult_Page(ctx, field)
|
||||
case "Results":
|
||||
return ec.fieldContext_PaginatedImagesResult_Results(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
|
||||
return nil, fmt.Errorf("no field named %q was found under type PaginatedImagesResult", field.Name)
|
||||
},
|
||||
}
|
||||
defer func() {
|
||||
@@ -4996,11 +4891,14 @@ func (ec *executionContext) _Query_ImageList(ctx context.Context, field graphql.
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.([]*ImageSummary)
|
||||
res := resTmp.(*PaginatedImagesResult)
|
||||
fc.Result = res
|
||||
return ec.marshalOImageSummary2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐImageSummaryᚄ(ctx, field.Selections, res)
|
||||
return ec.marshalNPaginatedImagesResult2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐPaginatedImagesResult(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Query_ImageList(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
@@ -5011,50 +4909,12 @@ func (ec *executionContext) fieldContext_Query_ImageList(ctx context.Context, fi
|
||||
IsResolver: true,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
switch field.Name {
|
||||
case "RepoName":
|
||||
return ec.fieldContext_ImageSummary_RepoName(ctx, field)
|
||||
case "Tag":
|
||||
return ec.fieldContext_ImageSummary_Tag(ctx, field)
|
||||
case "Digest":
|
||||
return ec.fieldContext_ImageSummary_Digest(ctx, field)
|
||||
case "ConfigDigest":
|
||||
return ec.fieldContext_ImageSummary_ConfigDigest(ctx, field)
|
||||
case "LastUpdated":
|
||||
return ec.fieldContext_ImageSummary_LastUpdated(ctx, field)
|
||||
case "IsSigned":
|
||||
return ec.fieldContext_ImageSummary_IsSigned(ctx, field)
|
||||
case "Size":
|
||||
return ec.fieldContext_ImageSummary_Size(ctx, field)
|
||||
case "Platform":
|
||||
return ec.fieldContext_ImageSummary_Platform(ctx, field)
|
||||
case "Vendor":
|
||||
return ec.fieldContext_ImageSummary_Vendor(ctx, field)
|
||||
case "Score":
|
||||
return ec.fieldContext_ImageSummary_Score(ctx, field)
|
||||
case "DownloadCount":
|
||||
return ec.fieldContext_ImageSummary_DownloadCount(ctx, field)
|
||||
case "Layers":
|
||||
return ec.fieldContext_ImageSummary_Layers(ctx, field)
|
||||
case "Description":
|
||||
return ec.fieldContext_ImageSummary_Description(ctx, field)
|
||||
case "Licenses":
|
||||
return ec.fieldContext_ImageSummary_Licenses(ctx, field)
|
||||
case "Labels":
|
||||
return ec.fieldContext_ImageSummary_Labels(ctx, field)
|
||||
case "Title":
|
||||
return ec.fieldContext_ImageSummary_Title(ctx, field)
|
||||
case "Source":
|
||||
return ec.fieldContext_ImageSummary_Source(ctx, field)
|
||||
case "Documentation":
|
||||
return ec.fieldContext_ImageSummary_Documentation(ctx, field)
|
||||
case "History":
|
||||
return ec.fieldContext_ImageSummary_History(ctx, field)
|
||||
case "Vulnerabilities":
|
||||
return ec.fieldContext_ImageSummary_Vulnerabilities(ctx, field)
|
||||
case "Authors":
|
||||
return ec.fieldContext_ImageSummary_Authors(ctx, field)
|
||||
case "Page":
|
||||
return ec.fieldContext_PaginatedImagesResult_Page(ctx, field)
|
||||
case "Results":
|
||||
return ec.fieldContext_PaginatedImagesResult_Results(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
|
||||
return nil, fmt.Errorf("no field named %q was found under type PaginatedImagesResult", field.Name)
|
||||
},
|
||||
}
|
||||
defer func() {
|
||||
@@ -8935,6 +8795,9 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||
}
|
||||
}()
|
||||
res = ec._Query_ImageListForCVE(ctx, field)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -8955,6 +8818,9 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||
}
|
||||
}()
|
||||
res = ec._Query_ImageListWithCVEFixed(ctx, field)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -8975,6 +8841,9 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||
}
|
||||
}()
|
||||
res = ec._Query_ImageListForDigest(ctx, field)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -9018,6 +8887,9 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||
}
|
||||
}()
|
||||
res = ec._Query_ImageList(ctx, field)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -10331,53 +10203,6 @@ func (ec *executionContext) marshalOImageSummary2ᚕᚖzotregistryᚗioᚋzotᚋ
|
||||
return ret
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOImageSummary2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐImageSummaryᚄ(ctx context.Context, sel ast.SelectionSet, v []*ImageSummary) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ret := make(graphql.Array, len(v))
|
||||
var wg sync.WaitGroup
|
||||
isLen1 := len(v) == 1
|
||||
if !isLen1 {
|
||||
wg.Add(len(v))
|
||||
}
|
||||
for i := range v {
|
||||
i := i
|
||||
fc := &graphql.FieldContext{
|
||||
Index: &i,
|
||||
Result: &v[i],
|
||||
}
|
||||
ctx := graphql.WithFieldContext(ctx, fc)
|
||||
f := func(i int) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = nil
|
||||
}
|
||||
}()
|
||||
if !isLen1 {
|
||||
defer wg.Done()
|
||||
}
|
||||
ret[i] = ec.marshalNImageSummary2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐImageSummary(ctx, sel, v[i])
|
||||
}
|
||||
if isLen1 {
|
||||
f(i)
|
||||
} else {
|
||||
go f(i)
|
||||
}
|
||||
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
for _, e := range ret {
|
||||
if e == graphql.Null {
|
||||
return graphql.Null
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOImageSummary2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐImageSummary(ctx context.Context, sel ast.SelectionSet, v *ImageSummary) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
|
||||
@@ -117,7 +117,7 @@ func FilterByDigest(digest string) repodb.FilterFunc {
|
||||
|
||||
func getImageListForDigest(ctx context.Context, digest string, repoDB repodb.RepoDB, cveInfo cveinfo.CveInfo,
|
||||
requestedPage *gql_generated.PageInput,
|
||||
) ([]*gql_generated.ImageSummary, error) {
|
||||
) (*gql_generated.PaginatedImagesResult, error) {
|
||||
imageList := make([]*gql_generated.ImageSummary, 0)
|
||||
|
||||
if requestedPage == nil {
|
||||
@@ -137,9 +137,9 @@ func getImageListForDigest(ctx context.Context, digest string, repoDB repodb.Rep
|
||||
}
|
||||
|
||||
// get all repos
|
||||
reposMeta, manifestMetaMap, _, err := repoDB.FilterTags(ctx, FilterByDigest(digest), pageInput)
|
||||
reposMeta, manifestMetaMap, pageInfo, err := repoDB.FilterTags(ctx, FilterByDigest(digest), pageInput)
|
||||
if err != nil {
|
||||
return []*gql_generated.ImageSummary{}, err
|
||||
return &gql_generated.PaginatedImagesResult{}, err
|
||||
}
|
||||
|
||||
for _, repoMeta := range reposMeta {
|
||||
@@ -148,7 +148,13 @@ func getImageListForDigest(ctx context.Context, digest string, repoDB repodb.Rep
|
||||
imageList = append(imageList, imageSummaries...)
|
||||
}
|
||||
|
||||
return imageList, nil
|
||||
return &gql_generated.PaginatedImagesResult{
|
||||
Results: imageList,
|
||||
Page: &gql_generated.PageInfo{
|
||||
TotalCount: pageInfo.TotalCount,
|
||||
ItemCount: pageInfo.ItemCount,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getImageSummary(ctx context.Context, repo, tag string, repoDB repodb.RepoDB,
|
||||
@@ -286,7 +292,7 @@ func getImageListForCVE(
|
||||
requestedPage *gql_generated.PageInput,
|
||||
repoDB repodb.RepoDB,
|
||||
log log.Logger,
|
||||
) ([]*gql_generated.ImageSummary, error) {
|
||||
) (*gql_generated.PaginatedImagesResult, error) {
|
||||
// Obtain all repos and tags
|
||||
// Infinite page to make sure we scan all repos in advance, before filtering results
|
||||
// The CVE scan logic is called from here, not in the actual filter,
|
||||
@@ -296,7 +302,7 @@ func getImageListForCVE(
|
||||
repodb.PageInput{Limit: 0, Offset: 0, SortBy: repodb.SortCriteria(gql_generated.SortCriteriaUpdateTime)},
|
||||
)
|
||||
if err != nil {
|
||||
return []*gql_generated.ImageSummary{}, err
|
||||
return &gql_generated.PaginatedImagesResult{}, err
|
||||
}
|
||||
|
||||
affectedImages := []common.TagInfo{}
|
||||
@@ -311,7 +317,7 @@ func getImageListForCVE(
|
||||
log.Error().Str("repo", repo).Str("CVE", cveID).Err(err).
|
||||
Msg("error getting image list for CVE from repo")
|
||||
|
||||
return []*gql_generated.ImageSummary{}, err
|
||||
return &gql_generated.PaginatedImagesResult{}, err
|
||||
}
|
||||
|
||||
affectedImages = append(affectedImages, tagsInfo...)
|
||||
@@ -336,9 +342,9 @@ func getImageListForCVE(
|
||||
}
|
||||
|
||||
// get all repos
|
||||
reposMeta, manifestMetaMap, _, err := repoDB.FilterTags(ctx, FilterByTagInfo(affectedImages), pageInput)
|
||||
reposMeta, manifestMetaMap, pageInfo, err := repoDB.FilterTags(ctx, FilterByTagInfo(affectedImages), pageInput)
|
||||
if err != nil {
|
||||
return []*gql_generated.ImageSummary{}, err
|
||||
return &gql_generated.PaginatedImagesResult{}, err
|
||||
}
|
||||
|
||||
for _, repoMeta := range reposMeta {
|
||||
@@ -347,7 +353,13 @@ func getImageListForCVE(
|
||||
imageList = append(imageList, imageSummaries...)
|
||||
}
|
||||
|
||||
return imageList, nil
|
||||
return &gql_generated.PaginatedImagesResult{
|
||||
Results: imageList,
|
||||
Page: &gql_generated.PageInfo{
|
||||
TotalCount: pageInfo.TotalCount,
|
||||
ItemCount: pageInfo.ItemCount,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getImageListWithCVEFixed(
|
||||
@@ -358,7 +370,7 @@ func getImageListWithCVEFixed(
|
||||
requestedPage *gql_generated.PageInput,
|
||||
repoDB repodb.RepoDB,
|
||||
log log.Logger,
|
||||
) ([]*gql_generated.ImageSummary, error) {
|
||||
) (*gql_generated.PaginatedImagesResult, error) {
|
||||
imageList := make([]*gql_generated.ImageSummary, 0)
|
||||
|
||||
log.Info().Str("repo", repo).Str("CVE", cveID).Msg("extracting list of tags where CVE is fixed")
|
||||
@@ -368,7 +380,10 @@ func getImageListWithCVEFixed(
|
||||
log.Error().Str("repo", repo).Str("CVE", cveID).Err(err).
|
||||
Msg("error getting image list with CVE fixed from repo")
|
||||
|
||||
return imageList, err
|
||||
return &gql_generated.PaginatedImagesResult{
|
||||
Page: &gql_generated.PageInfo{},
|
||||
Results: imageList,
|
||||
}, err
|
||||
}
|
||||
|
||||
// We're not interested in other vulnerabilities
|
||||
@@ -388,9 +403,9 @@ func getImageListWithCVEFixed(
|
||||
}
|
||||
|
||||
// get all repos
|
||||
reposMeta, manifestMetaMap, _, err := repoDB.FilterTags(ctx, FilterByTagInfo(tagsInfo), pageInput)
|
||||
reposMeta, manifestMetaMap, pageInfo, err := repoDB.FilterTags(ctx, FilterByTagInfo(tagsInfo), pageInput)
|
||||
if err != nil {
|
||||
return []*gql_generated.ImageSummary{}, err
|
||||
return &gql_generated.PaginatedImagesResult{}, err
|
||||
}
|
||||
|
||||
for _, repoMeta := range reposMeta {
|
||||
@@ -402,7 +417,13 @@ func getImageListWithCVEFixed(
|
||||
imageList = append(imageList, imageSummaries...)
|
||||
}
|
||||
|
||||
return imageList, nil
|
||||
return &gql_generated.PaginatedImagesResult{
|
||||
Results: imageList,
|
||||
Page: &gql_generated.PageInfo{
|
||||
TotalCount: pageInfo.TotalCount,
|
||||
ItemCount: pageInfo.ItemCount,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func repoListWithNewestImage(
|
||||
@@ -964,7 +985,7 @@ func searchingForRepos(query string) bool {
|
||||
|
||||
func getImageList(ctx context.Context, repo string, repoDB repodb.RepoDB, cveInfo cveinfo.CveInfo,
|
||||
requestedPage *gql_generated.PageInput, log log.Logger, //nolint:unparam
|
||||
) ([]*gql_generated.ImageSummary, error) {
|
||||
) (*gql_generated.PaginatedImagesResult, error) {
|
||||
imageList := make([]*gql_generated.ImageSummary, 0)
|
||||
|
||||
if requestedPage == nil {
|
||||
@@ -984,13 +1005,13 @@ func getImageList(ctx context.Context, repo string, repoDB repodb.RepoDB, cveInf
|
||||
}
|
||||
|
||||
// reposMeta, manifestMetaMap, err := repoDB.SearchRepos(ctx, repo, repodb.Filter{}, pageInput)
|
||||
reposMeta, manifestMetaMap, _, err := repoDB.FilterTags(ctx,
|
||||
reposMeta, manifestMetaMap, pageInfo, err := repoDB.FilterTags(ctx,
|
||||
func(repoMeta repodb.RepoMetadata, manifestMeta repodb.ManifestMetadata) bool {
|
||||
return true
|
||||
},
|
||||
pageInput)
|
||||
if err != nil {
|
||||
return []*gql_generated.ImageSummary{}, err
|
||||
return &gql_generated.PaginatedImagesResult{}, err
|
||||
}
|
||||
|
||||
for _, repoMeta := range reposMeta {
|
||||
@@ -1002,7 +1023,13 @@ func getImageList(ctx context.Context, repo string, repoDB repodb.RepoDB, cveInf
|
||||
imageList = append(imageList, imageSummaries...)
|
||||
}
|
||||
|
||||
return imageList, nil
|
||||
return &gql_generated.PaginatedImagesResult{
|
||||
Results: imageList,
|
||||
Page: &gql_generated.PageInfo{
|
||||
TotalCount: pageInfo.TotalCount,
|
||||
ItemCount: pageInfo.ItemCount,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getReferrers(store storage.ImageStore, repoName string, digest string, artifactTypes []string, log log.Logger) (
|
||||
|
||||
@@ -614,7 +614,7 @@ func TestImageListForDigest(t *testing.T) {
|
||||
|
||||
imageList, err := getImageListForDigest(responseContext, "test", mockSearchDB, mocks.CveInfoMock{}, nil)
|
||||
So(err, ShouldBeNil)
|
||||
So(imageList, ShouldBeEmpty)
|
||||
So(imageList.Results, ShouldBeEmpty)
|
||||
})
|
||||
|
||||
Convey("valid imageListForDigest returned for matching manifest digest", func() {
|
||||
@@ -677,12 +677,12 @@ func TestImageListForDigest(t *testing.T) {
|
||||
imageSummaries, err := getImageListForDigest(responseContext, manifestDigest,
|
||||
mockSearchDB, mocks.CveInfoMock{}, &pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(imageSummaries), ShouldEqual, 1)
|
||||
So(len(imageSummaries.Results), ShouldEqual, 1)
|
||||
|
||||
imageSummaries, err = getImageListForDigest(responseContext, "invalid",
|
||||
mockSearchDB, mocks.CveInfoMock{}, &pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(imageSummaries), ShouldEqual, 0)
|
||||
So(len(imageSummaries.Results), ShouldEqual, 0)
|
||||
})
|
||||
|
||||
Convey("valid imageListForDigest returned for matching config digest", func() {
|
||||
@@ -756,7 +756,7 @@ func TestImageListForDigest(t *testing.T) {
|
||||
imageSummaries, err := getImageListForDigest(responseContext, configDigest.String(),
|
||||
mockSearchDB, mocks.CveInfoMock{}, &pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(imageSummaries), ShouldEqual, 1)
|
||||
So(len(imageSummaries.Results), ShouldEqual, 1)
|
||||
})
|
||||
|
||||
Convey("valid imageListForDigest returned for matching layer digest", func() {
|
||||
@@ -832,7 +832,7 @@ func TestImageListForDigest(t *testing.T) {
|
||||
imageSummaries, err := getImageListForDigest(responseContext, layerDigest.String(),
|
||||
mockSearchDB, mocks.CveInfoMock{}, &pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(imageSummaries), ShouldEqual, 1)
|
||||
So(len(imageSummaries.Results), ShouldEqual, 1)
|
||||
})
|
||||
|
||||
Convey("valid imageListForDigest, multiple matching tags", func() {
|
||||
@@ -901,7 +901,7 @@ func TestImageListForDigest(t *testing.T) {
|
||||
imageSummaries, err := getImageListForDigest(responseContext, manifestDigest,
|
||||
mockSearchDB, mocks.CveInfoMock{}, &pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(imageSummaries), ShouldEqual, 2)
|
||||
So(len(imageSummaries.Results), ShouldEqual, 2)
|
||||
})
|
||||
|
||||
Convey("valid imageListForDigest, multiple matching tags limited by pageInput", func() {
|
||||
@@ -981,7 +981,7 @@ func TestImageListForDigest(t *testing.T) {
|
||||
imageSummaries, err := getImageListForDigest(responseContext, manifestDigest,
|
||||
mockSearchDB, mocks.CveInfoMock{}, &pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(imageSummaries), ShouldEqual, 1)
|
||||
So(len(imageSummaries.Results), ShouldEqual, 1)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1072,12 +1072,12 @@ func TestImageList(t *testing.T) {
|
||||
imageSummaries, err := getImageList(responseContext, "test", mockSearchDB,
|
||||
mocks.CveInfoMock{}, &pageInput, testLogger)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(imageSummaries), ShouldEqual, 1)
|
||||
So(len(imageSummaries.Results), ShouldEqual, 1)
|
||||
|
||||
imageSummaries, err = getImageList(responseContext, "invalid", mockSearchDB,
|
||||
mocks.CveInfoMock{}, &pageInput, testLogger)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(imageSummaries), ShouldEqual, 0)
|
||||
So(len(imageSummaries.Results), ShouldEqual, 0)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1878,9 +1878,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
"repo1:1.0.0",
|
||||
"repo2:2.0.0",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -1892,9 +1892,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
"repo2:2.0.0", "repo2:2.0.1",
|
||||
"repo3:3.0.1",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -1906,9 +1906,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
"repo2:2.0.0", "repo2:2.0.1", "repo2:2.1.0", "repo2:latest",
|
||||
"repo3:3.0.1", "repo3:3.1.0", "repo3:latest",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
})
|
||||
@@ -1926,9 +1926,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages := []string{
|
||||
"repo1:1.0.0",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -1940,9 +1940,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages = []string{
|
||||
"repo2:2.0.0",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -1950,13 +1950,13 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
|
||||
images, err = getImageListForCVE(responseContext, "CVE1", cveInfo, pageInput, repoDB, log)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(images), ShouldEqual, 0)
|
||||
So(len(images.Results), ShouldEqual, 0)
|
||||
|
||||
pageInput = getPageInput(1, 5)
|
||||
|
||||
images, err = getImageListForCVE(responseContext, "CVE1", cveInfo, pageInput, repoDB, log)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(images), ShouldEqual, 0)
|
||||
So(len(images.Results), ShouldEqual, 0)
|
||||
|
||||
pageInput = getPageInput(2, 0)
|
||||
|
||||
@@ -1967,9 +1967,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
"repo1:1.0.0",
|
||||
"repo2:2.0.0",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -1982,9 +1982,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
"repo1:1.0.0",
|
||||
"repo2:2.0.0",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -1996,9 +1996,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages = []string{
|
||||
"repo2:2.0.0",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2006,13 +2006,13 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
|
||||
images, err = getImageListForCVE(responseContext, "CVE1", cveInfo, pageInput, repoDB, log)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(images), ShouldEqual, 0)
|
||||
So(len(images.Results), ShouldEqual, 0)
|
||||
|
||||
pageInput = getPageInput(5, 5)
|
||||
|
||||
images, err = getImageListForCVE(responseContext, "CVE1", cveInfo, pageInput, repoDB, log)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(images), ShouldEqual, 0)
|
||||
So(len(images.Results), ShouldEqual, 0)
|
||||
|
||||
pageInput = getPageInput(5, 0)
|
||||
|
||||
@@ -2024,9 +2024,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
"repo2:2.0.0", "repo2:2.0.1",
|
||||
"repo3:3.0.1",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2039,9 +2039,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
"repo2:2.0.1",
|
||||
"repo3:3.0.1",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2054,9 +2054,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
"repo1:1.0.0", "repo1:1.0.1", "repo1:1.1.0", "repo1:latest",
|
||||
"repo2:2.0.0",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2069,9 +2069,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
"repo2:2.0.1", "repo2:2.1.0", "repo2:latest",
|
||||
"repo3:3.0.1", "repo3:3.1.0",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2083,9 +2083,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages = []string{
|
||||
"repo3:latest",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
})
|
||||
@@ -2102,9 +2102,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages := []string{
|
||||
"repo1:1.0.1", "repo1:1.1.0", "repo1:latest",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2114,15 +2114,15 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages = []string{
|
||||
"repo1:1.1.0", "repo1:latest",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
images, err = getImageListWithCVEFixed(responseContext, "CVE3", "repo1", cveInfo, nil, repoDB, log)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(images), ShouldEqual, 0)
|
||||
So(len(images.Results), ShouldEqual, 0)
|
||||
})
|
||||
|
||||
Convey("Paginated requests", func() {
|
||||
@@ -2138,9 +2138,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages := []string{
|
||||
"repo1:1.0.1",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2152,9 +2152,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages = []string{
|
||||
"repo1:1.1.0",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2166,9 +2166,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages = []string{
|
||||
"repo1:latest",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2176,13 +2176,13 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
|
||||
images, err = getImageListWithCVEFixed(responseContext, "CVE1", "repo1", cveInfo, pageInput, repoDB, log)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(images), ShouldEqual, 0)
|
||||
So(len(images.Results), ShouldEqual, 0)
|
||||
|
||||
pageInput = getPageInput(1, 10)
|
||||
|
||||
images, err = getImageListWithCVEFixed(responseContext, "CVE1", "repo1", cveInfo, pageInput, repoDB, log)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(images), ShouldEqual, 0)
|
||||
So(len(images.Results), ShouldEqual, 0)
|
||||
|
||||
pageInput = getPageInput(2, 0)
|
||||
|
||||
@@ -2192,9 +2192,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages = []string{
|
||||
"repo1:1.0.1", "repo1:1.1.0",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2206,9 +2206,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages = []string{
|
||||
"repo1:1.1.0", "repo1:latest",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2220,9 +2220,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages = []string{
|
||||
"repo1:latest",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2234,9 +2234,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages = []string{
|
||||
"repo1:1.0.1", "repo1:1.1.0", "repo1:latest",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2248,9 +2248,9 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
expectedImages = []string{
|
||||
"repo1:1.1.0", "repo1:latest",
|
||||
}
|
||||
So(len(images), ShouldEqual, len(expectedImages))
|
||||
So(len(images.Results), ShouldEqual, len(expectedImages))
|
||||
|
||||
for _, image := range images {
|
||||
for _, image := range images.Results {
|
||||
So(fmt.Sprintf("%s:%s", *image.RepoName, *image.Tag), ShouldBeIn, expectedImages)
|
||||
}
|
||||
|
||||
@@ -2258,7 +2258,7 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
|
||||
images, err = getImageListWithCVEFixed(responseContext, "CVE2", "repo1", cveInfo, pageInput, repoDB, log)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(images), ShouldEqual, 0)
|
||||
So(len(images.Results), ShouldEqual, 0)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -534,7 +534,7 @@ type Query {
|
||||
id: String!,
|
||||
"Sets the parameters of the requested page"
|
||||
requestedPage: PageInput
|
||||
): [ImageSummary!]
|
||||
): PaginatedImagesResult!
|
||||
|
||||
"""
|
||||
Returns a list of images that are no longer vulnerable to the CVE of the specified ID,
|
||||
@@ -547,7 +547,7 @@ type Query {
|
||||
image: String!,
|
||||
"Sets the parameters of the requested page"
|
||||
requestedPage: PageInput
|
||||
): [ImageSummary!]
|
||||
): PaginatedImagesResult!
|
||||
|
||||
"""
|
||||
Returns a list of images which contain the specified digest
|
||||
@@ -557,7 +557,7 @@ type Query {
|
||||
id: String!,
|
||||
"Sets the parameters of the requested page"
|
||||
requestedPage: PageInput
|
||||
): [ImageSummary!]
|
||||
): PaginatedImagesResult!
|
||||
|
||||
"""
|
||||
Returns a list of repositories with the newest tag (most recently created timestamp)
|
||||
@@ -575,7 +575,7 @@ type Query {
|
||||
repo: String!,
|
||||
"Sets the parameters of the requested page"
|
||||
requestedPage: PageInput
|
||||
): [ImageSummary!]
|
||||
): PaginatedImagesResult!
|
||||
|
||||
"""
|
||||
Obtain detailed information about a repository and container images within
|
||||
|
||||
@@ -23,25 +23,25 @@ func (r *queryResolver) CVEListForImage(ctx context.Context, image string, reque
|
||||
}
|
||||
|
||||
// ImageListForCve is the resolver for the ImageListForCVE field.
|
||||
func (r *queryResolver) ImageListForCve(ctx context.Context, id string, requestedPage *gql_generated.PageInput) ([]*gql_generated.ImageSummary, error) {
|
||||
func (r *queryResolver) ImageListForCve(ctx context.Context, id string, requestedPage *gql_generated.PageInput) (*gql_generated.PaginatedImagesResult, error) {
|
||||
if r.cveInfo == nil {
|
||||
return []*gql_generated.ImageSummary{}, zerr.ErrCVESearchDisabled
|
||||
return &gql_generated.PaginatedImagesResult{}, zerr.ErrCVESearchDisabled
|
||||
}
|
||||
|
||||
return getImageListForCVE(ctx, id, r.cveInfo, requestedPage, r.repoDB, r.log)
|
||||
}
|
||||
|
||||
// ImageListWithCVEFixed is the resolver for the ImageListWithCVEFixed field.
|
||||
func (r *queryResolver) ImageListWithCVEFixed(ctx context.Context, id string, image string, requestedPage *gql_generated.PageInput) ([]*gql_generated.ImageSummary, error) {
|
||||
func (r *queryResolver) ImageListWithCVEFixed(ctx context.Context, id string, image string, requestedPage *gql_generated.PageInput) (*gql_generated.PaginatedImagesResult, error) {
|
||||
if r.cveInfo == nil {
|
||||
return []*gql_generated.ImageSummary{}, zerr.ErrCVESearchDisabled
|
||||
return &gql_generated.PaginatedImagesResult{}, zerr.ErrCVESearchDisabled
|
||||
}
|
||||
|
||||
return getImageListWithCVEFixed(ctx, id, image, r.cveInfo, requestedPage, r.repoDB, r.log)
|
||||
}
|
||||
|
||||
// ImageListForDigest is the resolver for the ImageListForDigest field.
|
||||
func (r *queryResolver) ImageListForDigest(ctx context.Context, id string, requestedPage *gql_generated.PageInput) ([]*gql_generated.ImageSummary, error) {
|
||||
func (r *queryResolver) ImageListForDigest(ctx context.Context, id string, requestedPage *gql_generated.PageInput) (*gql_generated.PaginatedImagesResult, error) {
|
||||
r.log.Info().Msg("extracting repositories")
|
||||
|
||||
imgResultForDigest, err := getImageListForDigest(ctx, id, r.repoDB, r.cveInfo, requestedPage)
|
||||
@@ -64,7 +64,7 @@ func (r *queryResolver) RepoListWithNewestImage(ctx context.Context, requestedPa
|
||||
}
|
||||
|
||||
// ImageList is the resolver for the ImageList field.
|
||||
func (r *queryResolver) ImageList(ctx context.Context, repo string, requestedPage *gql_generated.PageInput) ([]*gql_generated.ImageSummary, error) {
|
||||
func (r *queryResolver) ImageList(ctx context.Context, repo string, requestedPage *gql_generated.PageInput) (*gql_generated.PaginatedImagesResult, error) {
|
||||
r.log.Info().Msg("extension api: getting a list of all images")
|
||||
|
||||
imageList, err := getImageList(ctx, repo, r.repoDB, r.cveInfo, requestedPage, r.log)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
The examples below only include the GraphQL query without any additional details on how to send them to a server. They were made with the GraphQL playground from the debug binary. You can also use curl to make these queries, here's an example:
|
||||
|
||||
```bash
|
||||
curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageListForCVE (id:\"CVE-2002-1119\") { Name Tags } }" }' http://localhost:8080/v2/_zot/ext/search
|
||||
curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageListForCVE (id:\"CVE-2002-1119\") { Results { Name Tags } } }" }' http://localhost:8080/v2/_zot/ext/search
|
||||
```
|
||||
|
||||
## List CVEs of given image
|
||||
@@ -88,22 +88,24 @@ curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList
|
||||
```graphql
|
||||
{
|
||||
ImageListForCVE(id: "CVE-2018-20651") {
|
||||
RepoName
|
||||
Tag
|
||||
Digest
|
||||
ConfigDigest
|
||||
LastUpdated
|
||||
IsSigned
|
||||
Size
|
||||
Platform {
|
||||
Os
|
||||
Arch
|
||||
Results{
|
||||
RepoName
|
||||
Tag
|
||||
Digest
|
||||
ConfigDigest
|
||||
LastUpdated
|
||||
IsSigned
|
||||
Size
|
||||
Platform {
|
||||
Os
|
||||
Arch
|
||||
}
|
||||
Vendor
|
||||
Score
|
||||
DownloadCount
|
||||
Licenses
|
||||
Title
|
||||
}
|
||||
Vendor
|
||||
Score
|
||||
DownloadCount
|
||||
Licenses
|
||||
Title
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -114,24 +116,26 @@ curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList
|
||||
{
|
||||
"data": {
|
||||
"ImageListForCVE": [
|
||||
{
|
||||
"RepoName": "centos",
|
||||
"Tag": "centos8",
|
||||
"Digest": "sha256:ac0dc62b48b7f683b49365fecef3b1f4d99fbd249b762e99f13f74938d85a6c8",
|
||||
"ConfigDigest": "sha256:98a5843635a2ccc7d72b269923a65721480de929f882143c6c0a0eb43f9a2869",
|
||||
"LastUpdated": "2022-10-17T16:36:09.1751694+03:00",
|
||||
"IsSigned": true,
|
||||
"Size": "83545800",
|
||||
"Platform": {
|
||||
"Os": "linux",
|
||||
"Arch": "amd64"
|
||||
{
|
||||
"Results": {
|
||||
"RepoName": "centos",
|
||||
"Tag": "centos8",
|
||||
"Digest": "sha256:ac0dc62b48b7f683b49365fecef3b1f4d99fbd249b762e99f13f74938d85a6c8",
|
||||
"ConfigDigest": "sha256:98a5843635a2ccc7d72b269923a65721480de929f882143c6c0a0eb43f9a2869",
|
||||
"LastUpdated": "2022-10-17T16:36:09.1751694+03:00",
|
||||
"IsSigned": true,
|
||||
"Size": "83545800",
|
||||
"Platform": {
|
||||
"Os": "linux",
|
||||
"Arch": "amd64"
|
||||
},
|
||||
"Vendor": "[The CentOS Project](https://github.com/CentOS/sig-cloud-instance-images)\n",
|
||||
"Score": null,
|
||||
"DownloadCount": 0,
|
||||
"Licenses": "View [license information](https://www.centos.org/legal/) for the software contained in this image.",
|
||||
"Title": "centos"
|
||||
},
|
||||
"Vendor": "[The CentOS Project](https://github.com/CentOS/sig-cloud-instance-images)\n",
|
||||
"Score": null,
|
||||
"DownloadCount": 0,
|
||||
"Licenses": "View [license information](https://www.centos.org/legal/) for the software contained in this image.",
|
||||
"Title": "centos"
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -144,11 +148,13 @@ curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList
|
||||
```graphql
|
||||
{
|
||||
ImageListWithCVEFixed(id: "CVE-2018-20651", image: "ubuntu") {
|
||||
RepoName
|
||||
Tag
|
||||
Digest
|
||||
ConfigDigest
|
||||
LastUpdated
|
||||
Results {
|
||||
RepoName
|
||||
Tag
|
||||
Digest
|
||||
ConfigDigest
|
||||
LastUpdated
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -160,11 +166,13 @@ curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList
|
||||
"data": {
|
||||
"ImageListWithCVEFixed": [
|
||||
{
|
||||
"RepoName": "ubuntu",
|
||||
"Tag": "latest",
|
||||
"Digest": "sha256:650d596072ad45c6b74f4923e2cfea8158da2fb3a7b8dbb0b9ae4da3088d0591",
|
||||
"ConfigDigest": "sha256:88eef892e29d5b11be933f13424ef885644a6a6978924fedfb51ba555278fe74",
|
||||
"LastUpdated": "2022-10-25T01:53:41.769246372Z"
|
||||
"Results": {
|
||||
"RepoName": "ubuntu",
|
||||
"Tag": "latest",
|
||||
"Digest": "sha256:650d596072ad45c6b74f4923e2cfea8158da2fb3a7b8dbb0b9ae4da3088d0591",
|
||||
"ConfigDigest": "sha256:88eef892e29d5b11be933f13424ef885644a6a6978924fedfb51ba555278fe74",
|
||||
"LastUpdated": "2022-10-25T01:53:41.769246372Z"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -180,9 +188,11 @@ curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList
|
||||
ImageListForDigest(
|
||||
id: "5f34d0bb0261d32d0b0bc91024b7d4e98d94b08a49615e08c8a5a65bc3a7e09f"
|
||||
) {
|
||||
RepoName
|
||||
Tag
|
||||
Title
|
||||
Results{
|
||||
RepoName
|
||||
Tag
|
||||
Title
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -194,9 +204,11 @@ curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList
|
||||
"data": {
|
||||
"ImageListForDigest": [
|
||||
{
|
||||
"RepoName": "centos",
|
||||
"Tag": "8",
|
||||
"Title": "CentOS Base Image"
|
||||
"Results": {
|
||||
"RepoName": "centos",
|
||||
"Tag": "8",
|
||||
"Title": "CentOS Base Image"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -285,10 +297,12 @@ curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList
|
||||
```graphql
|
||||
{
|
||||
ImageList (repo: "ubuntu") {
|
||||
Tag
|
||||
Digest
|
||||
LastUpdated
|
||||
Size
|
||||
Results {
|
||||
Tag
|
||||
Digest
|
||||
LastUpdated
|
||||
Size
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -300,16 +314,19 @@ curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList
|
||||
"data": {
|
||||
"ImageList": [
|
||||
{
|
||||
"Tag": "latest",
|
||||
"Digest": "sha256:650d596072ad45c6b74f4923e2cfea8158da2fb3a7b8dbb0b9ae4da3088d0591",
|
||||
"LastUpdated": "2022-10-25T01:53:41.769246372Z",
|
||||
"Size": "30426374"
|
||||
},
|
||||
{
|
||||
"Tag": "xenial",
|
||||
"Digest": "sha256:34de800b5da88feb7723a87ecbbf238afb63dbfe0c828838e26ac7458bef0ac5",
|
||||
"LastUpdated": "2021-08-31T01:21:30.672229355Z",
|
||||
"Size": "46499103"
|
||||
"Results":
|
||||
{
|
||||
"Tag": "latest",
|
||||
"Digest": "sha256:650d596072ad45c6b74f4923e2cfea8158da2fb3a7b8dbb0b9ae4da3088d0591",
|
||||
"LastUpdated": "2022-10-25T01:53:41.769246372Z",
|
||||
"Size": "30426374"
|
||||
},
|
||||
{
|
||||
"Tag": "xenial",
|
||||
"Digest": "sha256:34de800b5da88feb7723a87ecbbf238afb63dbfe0c828838e26ac7458bef0ac5",
|
||||
"LastUpdated": "2021-08-31T01:21:30.672229355Z",
|
||||
"Size": "46499103"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user