fix: ImageSummary should have author information (#976)

Signed-off-by: Ana-Roberta Lisca <ana.kagome@yahoo.com>
This commit is contained in:
Lisca Ana-Roberta 2022-11-11 01:02:17 +02:00 committed by GitHub
parent 97e7f7f756
commit 5eeba938ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 247 additions and 1 deletions

View File

@ -167,6 +167,7 @@ type ImageAnnotations struct {
Source string
Labels string
Vendor string
Authors string
}
/*
@ -195,6 +196,12 @@ func GetVendor(annotations map[string]string) string {
return GetAnnotationValue(annotations, ispec.AnnotationVendor, LabelAnnotationVendor)
}
func GetAuthors(annotations map[string]string) string {
authors := annotations[ispec.AnnotationAuthors]
return authors
}
func GetTitle(annotations map[string]string) string {
return GetAnnotationValue(annotations, ispec.AnnotationTitle, LabelAnnotationTitle)
}
@ -232,7 +239,7 @@ func GetAnnotations(annotations, labels map[string]string) ImageAnnotations {
documentation := GetDocumentation(annotations)
if documentation == "" {
documentation = GetDocumentation(annotations)
documentation = GetDocumentation(labels)
}
source := GetSource(annotations)
@ -255,6 +262,11 @@ func GetAnnotations(annotations, labels map[string]string) ImageAnnotations {
vendor = GetVendor(labels)
}
authors := GetAuthors(annotations)
if authors == "" {
authors = GetAuthors(labels)
}
return ImageAnnotations{
Description: description,
Title: title,
@ -263,5 +275,6 @@ func GetAnnotations(annotations, labels map[string]string) ImageAnnotations {
Licenses: licenses,
Labels: categories,
Vendor: vendor,
Authors: authors,
}
}

View File

@ -1984,6 +1984,150 @@ func TestGetRepositories(t *testing.T) {
})
}
func TestGlobalSearchImageAuthor(t *testing.T) {
port := GetFreePort()
baseURL := GetBaseURL(port)
conf := config.New()
conf.HTTP.Port = port
tempDir := t.TempDir()
conf.Storage.RootDirectory = tempDir
defaultVal := true
conf.Extensions = &extconf.ExtensionConfig{
Search: &extconf.SearchConfig{BaseConfig: extconf.BaseConfig{Enable: &defaultVal}},
}
conf.Extensions.Search.CVE = nil
ctlr := api.NewController(conf)
go func() {
// this blocks
if err := ctlr.Run(context.Background()); err != nil {
return
}
}()
// wait till ready
for {
_, err := resty.R().Get(baseURL)
if err == nil {
break
}
time.Sleep(100 * time.Millisecond)
}
// shut down server
defer func() {
ctx := context.Background()
_ = ctlr.Server.Shutdown(ctx)
}()
Convey("Test global search with author in manifest's annotations", t, func() {
cfg, layers, manifest, err := GetImageComponents(10000)
So(err, ShouldBeNil)
manifest.Annotations = make(map[string]string)
manifest.Annotations["org.opencontainers.image.authors"] = "author name"
err = UploadImage(
Image{
Config: cfg,
Layers: layers,
Manifest: manifest,
Tag: "latest",
}, baseURL, "repowithauthor")
So(err, ShouldBeNil)
query := `
{
GlobalSearch(query:""){
Images {
RepoName
Tag
LastUpdated
Size
IsSigned
Vendor
Score
Platform {
Os
Arch
}
Vulnerabilities {
Count
MaxSeverity
}
Authors
}
}
}`
resp, err := resty.R().Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(query))
So(resp, ShouldNotBeNil)
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, 200)
responseStruct := &GlobalSearchResultResp{}
err = json.Unmarshal(resp.Body(), responseStruct)
So(err, ShouldBeNil)
So(responseStruct.GlobalSearchResult.GlobalSearch.Images[0].Authors, ShouldEqual, "author name")
})
Convey("Test global search with author in manifest's config", t, func() {
cfg, layers, manifest, err := GetImageComponents(10000)
So(err, ShouldBeNil)
err = UploadImage(
Image{
Config: cfg,
Layers: layers,
Manifest: manifest,
Tag: "latest",
}, baseURL, "repowithauthorconfig")
So(err, ShouldBeNil)
query := `
{
GlobalSearch(query:""){
Images {
RepoName
Tag
LastUpdated
Size
IsSigned
Vendor
Score
Platform {
Os
Arch
}
Vulnerabilities {
Count
MaxSeverity
}
Authors
}
}
}`
resp, err := resty.R().Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(query))
So(resp, ShouldNotBeNil)
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, 200)
responseStruct := &GlobalSearchResultResp{}
err = json.Unmarshal(resp.Body(), responseStruct)
So(err, ShouldBeNil)
So(responseStruct.GlobalSearchResult.GlobalSearch.Images[1].Authors, ShouldEqual, "ZotUser")
})
}
func TestGlobalSearch(t *testing.T) {
Convey("Test global search", t, func() {
subpath := "/a"

View File

@ -40,6 +40,7 @@ type ImageSummary struct {
History []LayerHistory `json:"history"`
Layers []LayerSummary `json:"layers"`
Vulnerabilities ImageVulnerabilitySummary `json:"vulnerabilities"`
Authors string `json:"authors"`
}
type OsArch struct {

View File

@ -71,6 +71,7 @@ type ComplexityRoot struct {
}
ImageSummary struct {
Authors func(childComplexity int) int
ConfigDigest func(childComplexity int) int
Description func(childComplexity int) int
Digest func(childComplexity int) int
@ -287,6 +288,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.HistoryDescription.EmptyLayer(childComplexity), true
case "ImageSummary.Authors":
if e.complexity.ImageSummary.Authors == nil {
break
}
return e.complexity.ImageSummary.Authors(childComplexity), true
case "ImageSummary.ConfigDigest":
if e.complexity.ImageSummary.ConfigDigest == nil {
break
@ -849,6 +857,7 @@ type ImageSummary {
Documentation: String
History: [LayerHistory]
Vulnerabilities: ImageVulnerabilitySummary
Authors: String
}
type ImageVulnerabilitySummary {
@ -1576,6 +1585,8 @@ func (ec *executionContext) fieldContext_GlobalSearchResult_Images(ctx context.C
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)
}
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
},
@ -2746,6 +2757,47 @@ func (ec *executionContext) fieldContext_ImageSummary_Vulnerabilities(ctx contex
return fc, nil
}
func (ec *executionContext) _ImageSummary_Authors(ctx context.Context, field graphql.CollectedField, obj *ImageSummary) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_ImageSummary_Authors(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.Authors, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_ImageSummary_Authors(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "ImageSummary",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _ImageVulnerabilitySummary_MaxSeverity(ctx context.Context, field graphql.CollectedField, obj *ImageVulnerabilitySummary) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_ImageVulnerabilitySummary_MaxSeverity(ctx, field)
if err != nil {
@ -3395,6 +3447,8 @@ func (ec *executionContext) fieldContext_Query_ImageListForCVE(ctx context.Conte
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)
}
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
},
@ -3489,6 +3543,8 @@ func (ec *executionContext) fieldContext_Query_ImageListWithCVEFixed(ctx context
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)
}
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
},
@ -3583,6 +3639,8 @@ func (ec *executionContext) fieldContext_Query_ImageListForDigest(ctx context.Co
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)
}
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
},
@ -3743,6 +3801,8 @@ func (ec *executionContext) fieldContext_Query_ImageList(ctx context.Context, fi
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)
}
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
},
@ -3961,6 +4021,8 @@ func (ec *executionContext) fieldContext_Query_DerivedImageList(ctx context.Cont
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)
}
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
},
@ -4055,6 +4117,8 @@ func (ec *executionContext) fieldContext_Query_BaseImageList(ctx context.Context
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)
}
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
},
@ -4149,6 +4213,8 @@ func (ec *executionContext) fieldContext_Query_Image(ctx context.Context, field
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)
}
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
},
@ -4372,6 +4438,8 @@ func (ec *executionContext) fieldContext_RepoInfo_Images(ctx context.Context, fi
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)
}
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
},
@ -4770,6 +4838,8 @@ func (ec *executionContext) fieldContext_RepoSummary_NewestImage(ctx context.Con
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)
}
return nil, fmt.Errorf("no field named %q was found under type ImageSummary", field.Name)
},
@ -6915,6 +6985,10 @@ func (ec *executionContext) _ImageSummary(ctx context.Context, sel ast.Selection
out.Values[i] = ec._ImageSummary_Vulnerabilities(ctx, field, obj)
case "Authors":
out.Values[i] = ec._ImageSummary_Authors(ctx, field, obj)
default:
panic("unknown field " + strconv.Quote(field.Name))
}

View File

@ -62,6 +62,7 @@ type ImageSummary struct {
Documentation *string `json:"Documentation"`
History []*LayerHistory `json:"History"`
Vulnerabilities *ImageVulnerabilitySummary `json:"Vulnerabilities"`
Authors *string `json:"Authors"`
}
type ImageVulnerabilitySummary struct {

View File

@ -205,6 +205,11 @@ func repoListWithNewestImage(
}
}
authors := annotations.Authors
if authors == "" {
authors = imageConfigInfo.Author
}
tag := manifestTag
size := strconv.Itoa(int(imageSize))
manifestDigest := manifest.Digest.String()
@ -234,6 +239,7 @@ func repoListWithNewestImage(
MaxSeverity: &imageCveSummary.MaxSeverity,
Count: &imageCveSummary.Count,
},
Authors: &authors,
}
if manifest.Digest.String() == lastUpdatedTag.Digest.String() {
@ -402,6 +408,11 @@ func globalSearch(repoList []string, name, tag string, olu common.OciLayoutUtils
}
}
authors := annotations.Authors
if authors == "" {
authors = imageConfigInfo.Author
}
imageSummary := gql_generated.ImageSummary{
RepoName: &repo,
Tag: &manifestTag,
@ -423,6 +434,7 @@ func globalSearch(repoList []string, name, tag string, olu common.OciLayoutUtils
MaxSeverity: &imageCveSummary.MaxSeverity,
Count: &imageCveSummary.Count,
},
Authors: &authors,
}
if manifest.Digest.String() == lastUpdatedTag.Digest.String() {

View File

@ -73,6 +73,7 @@ type ImageSummary {
Documentation: String
History: [LayerHistory]
Vulnerabilities: ImageVulnerabilitySummary
Authors: String
}
type ImageVulnerabilitySummary {