fix: ImageSummary should have author information (#976)
Signed-off-by: Ana-Roberta Lisca <ana.kagome@yahoo.com>
This commit is contained in:
parent
97e7f7f756
commit
5eeba938ab
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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() {
|
||||
|
@ -73,6 +73,7 @@ type ImageSummary {
|
||||
Documentation: String
|
||||
History: [LayerHistory]
|
||||
Vulnerabilities: ImageVulnerabilitySummary
|
||||
Authors: String
|
||||
}
|
||||
|
||||
type ImageVulnerabilitySummary {
|
||||
|
Loading…
Reference in New Issue
Block a user