From 37d150e32f1b2006913ef2f516e48ba7b3a0e33e Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 2 Feb 2022 02:02:05 +0000 Subject: [PATCH] search: graphql api to give detailed repo info DetailedRepoInfo graphql api returns detailed repo info given repo name repo contains its manifests info Each manifest entry contains digest,signed, tag and layers info Each layer info containes digest, size Signed-off-by: Shivam Mishra --- go.mod | 2 +- pkg/extensions/search/common/common_test.go | 113 ++++ pkg/extensions/search/common/oci_layout.go | 78 +++ pkg/extensions/search/generated.go | 699 +++++++++++++++++++- pkg/extensions/search/models_gen.go | 16 + pkg/extensions/search/resolver.go | 46 ++ pkg/extensions/search/schema.graphql | 17 + 7 files changed, 942 insertions(+), 29 deletions(-) diff --git a/go.mod b/go.mod index 0bec6dc2..542c9d6b 100644 --- a/go.mod +++ b/go.mod @@ -41,6 +41,7 @@ require ( github.com/opencontainers/umoci v0.4.8-0.20210922062158-e60a0cc726e6 github.com/oras-project/artifacts-spec v1.0.0-draft.1 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 + github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.11.0 github.com/prometheus/client_model v0.2.0 github.com/rs/zerolog v1.26.0 @@ -271,7 +272,6 @@ require ( github.com/owenrumney/squealer v0.2.28 // indirect github.com/pelletier/go-toml v1.9.4 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/common v0.31.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect diff --git a/pkg/extensions/search/common/common_test.go b/pkg/extensions/search/common/common_test.go index ccbfe778..7f5e5696 100644 --- a/pkg/extensions/search/common/common_test.go +++ b/pkg/extensions/search/common/common_test.go @@ -36,6 +36,15 @@ type ImgResponsWithLatestTag struct { Errors []ErrorGQL `json:"errors"` } +type ExpandedRepoInfoResp struct { + ExpandedRepoInfo ExpandedRepoInfo `json:"data"` + Errors []ErrorGQL `json:"errors"` +} + +type ExpandedRepoInfo struct { + RepoInfo common.RepoInfo `json:"expandedRepoInfo"` +} + //nolint:tagliatelle // graphQL schema type ImgListWithLatestTag struct { Images []ImageInfo `json:"ImageListWithLatestTag"` @@ -311,6 +320,110 @@ func TestLatestTagSearchHTTP(t *testing.T) { }) } +func TestExpandedRepoInfo(t *testing.T) { + Convey("Test expanded repo info", t, func() { + err := testSetup() + if err != nil { + panic(err) + } + port := GetFreePort() + baseURL := GetBaseURL(port) + conf := config.New() + conf.HTTP.Port = port + conf.Storage.RootDirectory = rootDir + conf.Storage.SubPaths = make(map[string]config.StorageConfig) + conf.Storage.SubPaths["/a"] = config.StorageConfig{RootDirectory: subRootDir} + defaultVal := true + conf.Extensions = &extconf.ExtensionConfig{ + Search: &extconf.SearchConfig{Enable: &defaultVal}, + } + + conf.Extensions.Search.CVE = nil + + ctlr := api.NewController(conf) + + go func() { + // this blocks + if err := ctlr.Run(); 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) + }() + + resp, err := resty.R().Get(baseURL + "/v2/") + So(resp, ShouldNotBeNil) + So(err, ShouldBeNil) + So(resp.StatusCode(), ShouldEqual, 200) + + resp, err = resty.R().Get(baseURL + "/query") + So(resp, ShouldNotBeNil) + So(err, ShouldBeNil) + So(resp.StatusCode(), ShouldEqual, 200) + + query := "{ExpandedRepoInfo(repo:\"zot-test\"){Manifests%20{Digest%20IsSigned%20Tag%20Layers%20{Size%20Digest}}}}" + + resp, err = resty.R().Get(baseURL + "/query?query=" + query) + So(resp, ShouldNotBeNil) + So(err, ShouldBeNil) + So(resp.StatusCode(), ShouldEqual, 200) + + responseStruct := &ExpandedRepoInfoResp{} + + err = json.Unmarshal(resp.Body(), responseStruct) + So(err, ShouldBeNil) + So(len(responseStruct.ExpandedRepoInfo.RepoInfo.Manifests), ShouldNotEqual, 0) + So(len(responseStruct.ExpandedRepoInfo.RepoInfo.Manifests[0].Layers), ShouldNotEqual, 0) + + query = "{ExpandedRepoInfo(repo:\"\"){Manifests%20{Digest%20Tag%20IsSigned%20Layers%20{Size%20Digest}}}}" + + resp, err = resty.R().Get(baseURL + "/query?query=" + query) + So(resp, ShouldNotBeNil) + So(err, ShouldBeNil) + So(resp.StatusCode(), ShouldEqual, 200) + + query = "{ExpandedRepoInfo(repo:\"a/zot-test\"){Manifests%20{Digest%20Tag%20IsSigned%20%Layers%20{Size%20Digest}}}}" + resp, err = resty.R().Get(baseURL + "/query?query=" + query) + So(resp, ShouldNotBeNil) + So(err, ShouldBeNil) + So(resp.StatusCode(), ShouldEqual, 200) + + err = json.Unmarshal(resp.Body(), responseStruct) + So(err, ShouldBeNil) + So(len(responseStruct.ExpandedRepoInfo.RepoInfo.Manifests), ShouldNotEqual, 0) + So(len(responseStruct.ExpandedRepoInfo.RepoInfo.Manifests[0].Layers), ShouldNotEqual, 0) + + err = os.Remove(path.Join(rootDir, "zot-test/blobs/sha256", + "2bacca16b9df395fc855c14ccf50b12b58d35d468b8e7f25758aff90f89bf396")) + if err != nil { + panic(err) + } + + query = "{ExpandedRepoInfo(repo:\"zot-test\"){Manifests%20{Digest%20Tag%20IsSigned%20%Layers%20{Size%20Digest}}}}" + + resp, err = resty.R().Get(baseURL + "/query?query=" + query) + So(resp, ShouldNotBeNil) + So(err, ShouldBeNil) + So(resp.StatusCode(), ShouldEqual, 200) + + err = json.Unmarshal(resp.Body(), responseStruct) + So(err, ShouldBeNil) + }) +} + func TestUtilsMethod(t *testing.T) { Convey("Test utils", t, func() { // Test GetRepo method diff --git a/pkg/extensions/search/common/oci_layout.go b/pkg/extensions/search/common/oci_layout.go index db239af9..f4131fab 100644 --- a/pkg/extensions/search/common/oci_layout.go +++ b/pkg/extensions/search/common/oci_layout.go @@ -5,6 +5,7 @@ import ( "encoding/json" goerrors "errors" "path" + "strconv" "strings" "time" @@ -17,12 +18,30 @@ import ( "zotregistry.io/zot/pkg/storage" ) +const cosignedAnnotation = "dev.cosign.signature.baseimage" + // OciLayoutInfo ... type OciLayoutUtils struct { Log log.Logger StoreController storage.StoreController } +type RepoInfo struct { + Manifests []Manifest `json:"manifests"` +} + +type Manifest struct { + Tag string `json:"tag"` + Digest string `json:"digest"` + IsSigned bool `json:"isSigned"` + Layers []Layer `json:"layers"` +} + +type Layer struct { + Size string `json:"size"` + Digest string `json:"digest"` +} + // NewOciLayoutUtils initializes a new OciLayoutUtils object. func NewOciLayoutUtils(storeController storage.StoreController, log log.Logger) *OciLayoutUtils { return &OciLayoutUtils{Log: log, StoreController: storeController} @@ -183,6 +202,65 @@ func (olu OciLayoutUtils) GetImageTagsWithTimestamp(repo string) ([]TagInfo, err return tagsInfo, nil } +func (olu OciLayoutUtils) GetExpandedRepoInfo(name string) (RepoInfo, error) { + repo := RepoInfo{} + + manifests := make([]Manifest, 0) + + manifestList, err := olu.GetImageManifests(name) + if err != nil { + olu.Log.Error().Err(err).Msg("error getting image manifests") + + return RepoInfo{}, err + } + + for _, manifest := range manifestList { + manifestInfo := Manifest{} + + manifestInfo.Digest = manifest.Digest.Encoded() + + manifestInfo.IsSigned = false + + tag, ok := manifest.Annotations[ispec.AnnotationRefName] + if !ok { + tag = "latest" + } + + manifestInfo.Tag = tag + + manifest, err := olu.GetImageBlobManifest(name, manifest.Digest) + if err != nil { + olu.Log.Error().Err(err).Msg("error getting image manifest blob") + + return RepoInfo{}, err + } + + layers := make([]Layer, 0) + + for _, layer := range manifest.Layers { + layerInfo := Layer{} + + layerInfo.Digest = layer.Digest.Hex + + layerInfo.Size = strconv.FormatInt(layer.Size, 10) + + layers = append(layers, layerInfo) + + if _, ok := layer.Annotations[cosignedAnnotation]; ok { + manifestInfo.IsSigned = true + } + } + + manifestInfo.Layers = layers + + manifests = append(manifests, manifestInfo) + } + + repo.Manifests = manifests + + return repo, nil +} + func GetImageDirAndTag(imageName string) (string, string) { var imageDir string diff --git a/pkg/extensions/search/generated.go b/pkg/extensions/search/generated.go index add3261a..beced48c 100644 --- a/pkg/extensions/search/generated.go +++ b/pkg/extensions/search/generated.go @@ -82,6 +82,18 @@ type ComplexityRoot struct { Tags func(childComplexity int) int } + LayerInfo struct { + Digest func(childComplexity int) int + Size func(childComplexity int) int + } + + ManifestInfo struct { + Digest func(childComplexity int) int + IsSigned func(childComplexity int) int + Layers func(childComplexity int) int + Tag func(childComplexity int) int + } + PackageInfo struct { FixedVersion func(childComplexity int) int InstalledVersion func(childComplexity int) int @@ -90,12 +102,17 @@ type ComplexityRoot struct { Query struct { CVEListForImage func(childComplexity int, image string) int + ExpandedRepoInfo func(childComplexity int, repo string) int ImageListForCve func(childComplexity int, id string) int ImageListForDigest func(childComplexity int, id string) int ImageListWithCVEFixed func(childComplexity int, id string, image string) int ImageListWithLatestTag func(childComplexity int) int } + RepoInfo struct { + Manifests func(childComplexity int) int + } + TagInfo struct { Digest func(childComplexity int) int Name func(childComplexity int) int @@ -109,6 +126,7 @@ type QueryResolver interface { ImageListWithCVEFixed(ctx context.Context, id string, image string) (*ImgResultForFixedCve, error) ImageListForDigest(ctx context.Context, id string) ([]*ImgResultForDigest, error) ImageListWithLatestTag(ctx context.Context) ([]*ImageInfo, error) + ExpandedRepoInfo(ctx context.Context, repo string) (*RepoInfo, error) } type executableSchema struct { @@ -266,6 +284,48 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.ImgResultForFixedCve.Tags(childComplexity), true + case "LayerInfo.Digest": + if e.complexity.LayerInfo.Digest == nil { + break + } + + return e.complexity.LayerInfo.Digest(childComplexity), true + + case "LayerInfo.Size": + if e.complexity.LayerInfo.Size == nil { + break + } + + return e.complexity.LayerInfo.Size(childComplexity), true + + case "ManifestInfo.Digest": + if e.complexity.ManifestInfo.Digest == nil { + break + } + + return e.complexity.ManifestInfo.Digest(childComplexity), true + + case "ManifestInfo.IsSigned": + if e.complexity.ManifestInfo.IsSigned == nil { + break + } + + return e.complexity.ManifestInfo.IsSigned(childComplexity), true + + case "ManifestInfo.Layers": + if e.complexity.ManifestInfo.Layers == nil { + break + } + + return e.complexity.ManifestInfo.Layers(childComplexity), true + + case "ManifestInfo.Tag": + if e.complexity.ManifestInfo.Tag == nil { + break + } + + return e.complexity.ManifestInfo.Tag(childComplexity), true + case "PackageInfo.FixedVersion": if e.complexity.PackageInfo.FixedVersion == nil { break @@ -299,6 +359,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.CVEListForImage(childComplexity, args["image"].(string)), true + case "Query.ExpandedRepoInfo": + if e.complexity.Query.ExpandedRepoInfo == nil { + break + } + + args, err := ec.field_Query_ExpandedRepoInfo_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.ExpandedRepoInfo(childComplexity, args["repo"].(string)), true + case "Query.ImageListForCVE": if e.complexity.Query.ImageListForCve == nil { break @@ -342,6 +414,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.ImageListWithLatestTag(childComplexity), true + case "RepoInfo.Manifests": + if e.complexity.RepoInfo.Manifests == nil { + break + } + + return e.complexity.RepoInfo.Manifests(childComplexity), true + case "TagInfo.Digest": if e.complexity.TagInfo.Digest == nil { break @@ -465,12 +544,29 @@ type ImageInfo { Labels: String } +type RepoInfo { + Manifests: [ManifestInfo] +} + +type ManifestInfo { + Digest: String + Tag: String + IsSigned: Boolean + Layers: [LayerInfo] +} + +type LayerInfo { + Size: String # Int64 is not supported. + Digest: String +} + type Query { CVEListForImage(image: String!) :CVEResultForImage ImageListForCVE(id: String!) :[ImgResultForCVE] ImageListWithCVEFixed(id: String!, image: String!) :ImgResultForFixedCVE ImageListForDigest(id: String!) :[ImgResultForDigest] ImageListWithLatestTag:[ImageInfo] + ExpandedRepoInfo(repo: String!):RepoInfo } `, BuiltIn: false}, } @@ -540,6 +636,21 @@ func (ec *executionContext) field_Query_CVEListForImage_args(ctx context.Context return args, nil } +func (ec *executionContext) field_Query_ExpandedRepoInfo_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["repo"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("repo")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["repo"] = arg0 + return args, nil +} + func (ec *executionContext) field_Query_ImageListForCVE_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -831,7 +942,7 @@ func (ec *executionContext) _CVE_PackageList(ctx context.Context, field graphql. } res := resTmp.([]*PackageInfo) fc.Result = res - return ec.marshalOPackageInfo2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐPackageInfo(ctx, field.Selections, res) + return ec.marshalOPackageInfo2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐPackageInfo(ctx, field.Selections, res) } func (ec *executionContext) _CVEResultForImage_Tag(ctx context.Context, field graphql.CollectedField, obj *CVEResultForImage) (ret graphql.Marshaler) { @@ -889,7 +1000,7 @@ func (ec *executionContext) _CVEResultForImage_CVEList(ctx context.Context, fiel } res := resTmp.([]*Cve) fc.Result = res - return ec.marshalOCVE2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐCve(ctx, field.Selections, res) + return ec.marshalOCVE2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐCve(ctx, field.Selections, res) } func (ec *executionContext) _ImageInfo_Name(ctx context.Context, field graphql.CollectedField, obj *ImageInfo) (ret graphql.Marshaler) { @@ -1266,7 +1377,181 @@ func (ec *executionContext) _ImgResultForFixedCVE_Tags(ctx context.Context, fiel } res := resTmp.([]*TagInfo) fc.Result = res - return ec.marshalOTagInfo2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐTagInfo(ctx, field.Selections, res) + return ec.marshalOTagInfo2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐTagInfo(ctx, field.Selections, res) +} + +func (ec *executionContext) _LayerInfo_Size(ctx context.Context, field graphql.CollectedField, obj *LayerInfo) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "LayerInfo", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Size, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _LayerInfo_Digest(ctx context.Context, field graphql.CollectedField, obj *LayerInfo) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "LayerInfo", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Digest, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _ManifestInfo_Digest(ctx context.Context, field graphql.CollectedField, obj *ManifestInfo) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ManifestInfo", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Digest, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _ManifestInfo_Tag(ctx context.Context, field graphql.CollectedField, obj *ManifestInfo) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ManifestInfo", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Tag, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _ManifestInfo_IsSigned(ctx context.Context, field graphql.CollectedField, obj *ManifestInfo) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ManifestInfo", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsSigned, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*bool) + fc.Result = res + return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) +} + +func (ec *executionContext) _ManifestInfo_Layers(ctx context.Context, field graphql.CollectedField, obj *ManifestInfo) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ManifestInfo", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Layers, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*LayerInfo) + fc.Result = res + return ec.marshalOLayerInfo2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐLayerInfo(ctx, field.Selections, res) } func (ec *executionContext) _PackageInfo_Name(ctx context.Context, field graphql.CollectedField, obj *PackageInfo) (ret graphql.Marshaler) { @@ -1389,7 +1674,7 @@ func (ec *executionContext) _Query_CVEListForImage(ctx context.Context, field gr } res := resTmp.(*CVEResultForImage) fc.Result = res - return ec.marshalOCVEResultForImage2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐCVEResultForImage(ctx, field.Selections, res) + return ec.marshalOCVEResultForImage2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐCVEResultForImage(ctx, field.Selections, res) } func (ec *executionContext) _Query_ImageListForCVE(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -1425,7 +1710,7 @@ func (ec *executionContext) _Query_ImageListForCVE(ctx context.Context, field gr } res := resTmp.([]*ImgResultForCve) fc.Result = res - return ec.marshalOImgResultForCVE2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForCve(ctx, field.Selections, res) + return ec.marshalOImgResultForCVE2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForCve(ctx, field.Selections, res) } func (ec *executionContext) _Query_ImageListWithCVEFixed(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -1461,7 +1746,7 @@ func (ec *executionContext) _Query_ImageListWithCVEFixed(ctx context.Context, fi } res := resTmp.(*ImgResultForFixedCve) fc.Result = res - return ec.marshalOImgResultForFixedCVE2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForFixedCve(ctx, field.Selections, res) + return ec.marshalOImgResultForFixedCVE2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForFixedCve(ctx, field.Selections, res) } func (ec *executionContext) _Query_ImageListForDigest(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -1497,7 +1782,7 @@ func (ec *executionContext) _Query_ImageListForDigest(ctx context.Context, field } res := resTmp.([]*ImgResultForDigest) fc.Result = res - return ec.marshalOImgResultForDigest2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForDigest(ctx, field.Selections, res) + return ec.marshalOImgResultForDigest2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForDigest(ctx, field.Selections, res) } func (ec *executionContext) _Query_ImageListWithLatestTag(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -1526,7 +1811,43 @@ func (ec *executionContext) _Query_ImageListWithLatestTag(ctx context.Context, f } res := resTmp.([]*ImageInfo) fc.Result = res - return ec.marshalOImageInfo2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImageInfo(ctx, field.Selections, res) + return ec.marshalOImageInfo2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImageInfo(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_ExpandedRepoInfo(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_ExpandedRepoInfo_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ExpandedRepoInfo(rctx, args["repo"].(string)) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*RepoInfo) + fc.Result = res + return ec.marshalORepoInfo2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐRepoInfo(ctx, field.Selections, res) } func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -1594,6 +1915,35 @@ func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.C return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) } +func (ec *executionContext) _RepoInfo_Manifests(ctx context.Context, field graphql.CollectedField, obj *RepoInfo) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "RepoInfo", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Manifests, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*ManifestInfo) + fc.Result = res + return ec.marshalOManifestInfo2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐManifestInfo(ctx, field.Selections, res) +} + func (ec *executionContext) _TagInfo_Name(ctx context.Context, field graphql.CollectedField, obj *TagInfo) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -1806,6 +2156,38 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2852,6 +3234,62 @@ func (ec *executionContext) _ImgResultForFixedCVE(ctx context.Context, sel ast.S return out } +var layerInfoImplementors = []string{"LayerInfo"} + +func (ec *executionContext) _LayerInfo(ctx context.Context, sel ast.SelectionSet, obj *LayerInfo) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, layerInfoImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("LayerInfo") + case "Size": + out.Values[i] = ec._LayerInfo_Size(ctx, field, obj) + case "Digest": + out.Values[i] = ec._LayerInfo_Digest(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var manifestInfoImplementors = []string{"ManifestInfo"} + +func (ec *executionContext) _ManifestInfo(ctx context.Context, sel ast.SelectionSet, obj *ManifestInfo) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, manifestInfoImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ManifestInfo") + case "Digest": + out.Values[i] = ec._ManifestInfo_Digest(ctx, field, obj) + case "Tag": + out.Values[i] = ec._ManifestInfo_Tag(ctx, field, obj) + case "IsSigned": + out.Values[i] = ec._ManifestInfo_IsSigned(ctx, field, obj) + case "Layers": + out.Values[i] = ec._ManifestInfo_Layers(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var packageInfoImplementors = []string{"PackageInfo"} func (ec *executionContext) _PackageInfo(ctx context.Context, sel ast.SelectionSet, obj *PackageInfo) graphql.Marshaler { @@ -2950,6 +3388,17 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr res = ec._Query_ImageListWithLatestTag(ctx, field) return res }) + case "ExpandedRepoInfo": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_ExpandedRepoInfo(ctx, field) + return res + }) case "__type": out.Values[i] = ec._Query___type(ctx, field) case "__schema": @@ -2965,6 +3414,30 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr return out } +var repoInfoImplementors = []string{"RepoInfo"} + +func (ec *executionContext) _RepoInfo(ctx context.Context, sel ast.SelectionSet, obj *RepoInfo) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, repoInfoImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("RepoInfo") + case "Manifests": + out.Values[i] = ec._RepoInfo_Manifests(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var tagInfoImplementors = []string{"TagInfo"} func (ec *executionContext) _TagInfo(ctx context.Context, sel ast.SelectionSet, obj *TagInfo) graphql.Marshaler { @@ -3021,6 +3494,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3306,6 +3784,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3379,6 +3864,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3428,6 +3920,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3469,6 +3968,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3521,7 +4027,7 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast return graphql.MarshalBoolean(*v) } -func (ec *executionContext) marshalOCVE2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐCve(ctx context.Context, sel ast.SelectionSet, v []*Cve) graphql.Marshaler { +func (ec *executionContext) marshalOCVE2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐCve(ctx context.Context, sel ast.SelectionSet, v []*Cve) graphql.Marshaler { if v == nil { return graphql.Null } @@ -3548,7 +4054,7 @@ func (ec *executionContext) marshalOCVE2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkg if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOCVE2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐCve(ctx, sel, v[i]) + ret[i] = ec.marshalOCVE2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐCve(ctx, sel, v[i]) } if isLen1 { f(i) @@ -3558,24 +4064,25 @@ func (ec *executionContext) marshalOCVE2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkg } wg.Wait() + return ret } -func (ec *executionContext) marshalOCVE2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐCve(ctx context.Context, sel ast.SelectionSet, v *Cve) graphql.Marshaler { +func (ec *executionContext) marshalOCVE2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐCve(ctx context.Context, sel ast.SelectionSet, v *Cve) graphql.Marshaler { if v == nil { return graphql.Null } return ec._CVE(ctx, sel, v) } -func (ec *executionContext) marshalOCVEResultForImage2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐCVEResultForImage(ctx context.Context, sel ast.SelectionSet, v *CVEResultForImage) graphql.Marshaler { +func (ec *executionContext) marshalOCVEResultForImage2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐCVEResultForImage(ctx context.Context, sel ast.SelectionSet, v *CVEResultForImage) graphql.Marshaler { if v == nil { return graphql.Null } return ec._CVEResultForImage(ctx, sel, v) } -func (ec *executionContext) marshalOImageInfo2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImageInfo(ctx context.Context, sel ast.SelectionSet, v []*ImageInfo) graphql.Marshaler { +func (ec *executionContext) marshalOImageInfo2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImageInfo(ctx context.Context, sel ast.SelectionSet, v []*ImageInfo) graphql.Marshaler { if v == nil { return graphql.Null } @@ -3602,7 +4109,7 @@ func (ec *executionContext) marshalOImageInfo2ᚕᚖgithubᚗcomᚋanuvuᚋzot if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOImageInfo2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImageInfo(ctx, sel, v[i]) + ret[i] = ec.marshalOImageInfo2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImageInfo(ctx, sel, v[i]) } if isLen1 { f(i) @@ -3612,17 +4119,18 @@ func (ec *executionContext) marshalOImageInfo2ᚕᚖgithubᚗcomᚋanuvuᚋzot } wg.Wait() + return ret } -func (ec *executionContext) marshalOImageInfo2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImageInfo(ctx context.Context, sel ast.SelectionSet, v *ImageInfo) graphql.Marshaler { +func (ec *executionContext) marshalOImageInfo2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImageInfo(ctx context.Context, sel ast.SelectionSet, v *ImageInfo) graphql.Marshaler { if v == nil { return graphql.Null } return ec._ImageInfo(ctx, sel, v) } -func (ec *executionContext) marshalOImgResultForCVE2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForCve(ctx context.Context, sel ast.SelectionSet, v []*ImgResultForCve) graphql.Marshaler { +func (ec *executionContext) marshalOImgResultForCVE2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForCve(ctx context.Context, sel ast.SelectionSet, v []*ImgResultForCve) graphql.Marshaler { if v == nil { return graphql.Null } @@ -3649,7 +4157,7 @@ func (ec *executionContext) marshalOImgResultForCVE2ᚕᚖgithubᚗcomᚋanuvu if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOImgResultForCVE2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForCve(ctx, sel, v[i]) + ret[i] = ec.marshalOImgResultForCVE2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForCve(ctx, sel, v[i]) } if isLen1 { f(i) @@ -3659,17 +4167,18 @@ func (ec *executionContext) marshalOImgResultForCVE2ᚕᚖgithubᚗcomᚋanuvu } wg.Wait() + return ret } -func (ec *executionContext) marshalOImgResultForCVE2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForCve(ctx context.Context, sel ast.SelectionSet, v *ImgResultForCve) graphql.Marshaler { +func (ec *executionContext) marshalOImgResultForCVE2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForCve(ctx context.Context, sel ast.SelectionSet, v *ImgResultForCve) graphql.Marshaler { if v == nil { return graphql.Null } return ec._ImgResultForCVE(ctx, sel, v) } -func (ec *executionContext) marshalOImgResultForDigest2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForDigest(ctx context.Context, sel ast.SelectionSet, v []*ImgResultForDigest) graphql.Marshaler { +func (ec *executionContext) marshalOImgResultForDigest2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForDigest(ctx context.Context, sel ast.SelectionSet, v []*ImgResultForDigest) graphql.Marshaler { if v == nil { return graphql.Null } @@ -3696,7 +4205,7 @@ func (ec *executionContext) marshalOImgResultForDigest2ᚕᚖgithubᚗcomᚋanuv if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOImgResultForDigest2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForDigest(ctx, sel, v[i]) + ret[i] = ec.marshalOImgResultForDigest2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForDigest(ctx, sel, v[i]) } if isLen1 { f(i) @@ -3706,24 +4215,25 @@ func (ec *executionContext) marshalOImgResultForDigest2ᚕᚖgithubᚗcomᚋanuv } wg.Wait() + return ret } -func (ec *executionContext) marshalOImgResultForDigest2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForDigest(ctx context.Context, sel ast.SelectionSet, v *ImgResultForDigest) graphql.Marshaler { +func (ec *executionContext) marshalOImgResultForDigest2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForDigest(ctx context.Context, sel ast.SelectionSet, v *ImgResultForDigest) graphql.Marshaler { if v == nil { return graphql.Null } return ec._ImgResultForDigest(ctx, sel, v) } -func (ec *executionContext) marshalOImgResultForFixedCVE2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForFixedCve(ctx context.Context, sel ast.SelectionSet, v *ImgResultForFixedCve) graphql.Marshaler { +func (ec *executionContext) marshalOImgResultForFixedCVE2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐImgResultForFixedCve(ctx context.Context, sel ast.SelectionSet, v *ImgResultForFixedCve) graphql.Marshaler { if v == nil { return graphql.Null } return ec._ImgResultForFixedCVE(ctx, sel, v) } -func (ec *executionContext) marshalOPackageInfo2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐPackageInfo(ctx context.Context, sel ast.SelectionSet, v []*PackageInfo) graphql.Marshaler { +func (ec *executionContext) marshalOLayerInfo2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐLayerInfo(ctx context.Context, sel ast.SelectionSet, v []*LayerInfo) graphql.Marshaler { if v == nil { return graphql.Null } @@ -3750,7 +4260,7 @@ func (ec *executionContext) marshalOPackageInfo2ᚕᚖgithubᚗcomᚋanuvuᚋzot if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOPackageInfo2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐPackageInfo(ctx, sel, v[i]) + ret[i] = ec.marshalOLayerInfo2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐLayerInfo(ctx, sel, v[i]) } if isLen1 { f(i) @@ -3760,16 +4270,120 @@ func (ec *executionContext) marshalOPackageInfo2ᚕᚖgithubᚗcomᚋanuvuᚋzot } wg.Wait() + return ret } -func (ec *executionContext) marshalOPackageInfo2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐPackageInfo(ctx context.Context, sel ast.SelectionSet, v *PackageInfo) graphql.Marshaler { +func (ec *executionContext) marshalOLayerInfo2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐLayerInfo(ctx context.Context, sel ast.SelectionSet, v *LayerInfo) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._LayerInfo(ctx, sel, v) +} + +func (ec *executionContext) marshalOManifestInfo2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐManifestInfo(ctx context.Context, sel ast.SelectionSet, v []*ManifestInfo) 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.marshalOManifestInfo2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐManifestInfo(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalOManifestInfo2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐManifestInfo(ctx context.Context, sel ast.SelectionSet, v *ManifestInfo) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._ManifestInfo(ctx, sel, v) +} + +func (ec *executionContext) marshalOPackageInfo2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐPackageInfo(ctx context.Context, sel ast.SelectionSet, v []*PackageInfo) 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.marshalOPackageInfo2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐPackageInfo(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalOPackageInfo2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐPackageInfo(ctx context.Context, sel ast.SelectionSet, v *PackageInfo) graphql.Marshaler { if v == nil { return graphql.Null } return ec._PackageInfo(ctx, sel, v) } +func (ec *executionContext) marshalORepoInfo2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐRepoInfo(ctx context.Context, sel ast.SelectionSet, v *RepoInfo) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._RepoInfo(ctx, sel, v) +} + func (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) { res, err := graphql.UnmarshalString(v) return res, graphql.ErrorOnPath(ctx, err) @@ -3830,7 +4444,7 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as return graphql.MarshalString(*v) } -func (ec *executionContext) marshalOTagInfo2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐTagInfo(ctx context.Context, sel ast.SelectionSet, v []*TagInfo) graphql.Marshaler { +func (ec *executionContext) marshalOTagInfo2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐTagInfo(ctx context.Context, sel ast.SelectionSet, v []*TagInfo) graphql.Marshaler { if v == nil { return graphql.Null } @@ -3857,7 +4471,7 @@ func (ec *executionContext) marshalOTagInfo2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋp if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOTagInfo2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐTagInfo(ctx, sel, v[i]) + ret[i] = ec.marshalOTagInfo2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐTagInfo(ctx, sel, v[i]) } if isLen1 { f(i) @@ -3867,10 +4481,11 @@ func (ec *executionContext) marshalOTagInfo2ᚕᚖgithubᚗcomᚋanuvuᚋzotᚋp } wg.Wait() + return ret } -func (ec *executionContext) marshalOTagInfo2ᚖgithubᚗcomᚋanuvuᚋzotᚋpkgᚋextensionsᚋsearchᚐTagInfo(ctx context.Context, sel ast.SelectionSet, v *TagInfo) graphql.Marshaler { +func (ec *executionContext) marshalOTagInfo2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚐTagInfo(ctx context.Context, sel ast.SelectionSet, v *TagInfo) graphql.Marshaler { if v == nil { return graphql.Null } @@ -3929,6 +4544,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3969,6 +4591,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -4009,6 +4638,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -4056,6 +4692,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/pkg/extensions/search/models_gen.go b/pkg/extensions/search/models_gen.go index 38eb9e0f..0f5eb12c 100644 --- a/pkg/extensions/search/models_gen.go +++ b/pkg/extensions/search/models_gen.go @@ -44,12 +44,28 @@ type ImgResultForFixedCve struct { Tags []*TagInfo `json:"Tags"` } +type LayerInfo struct { + Size *string `json:"Size"` + Digest *string `json:"Digest"` +} + +type ManifestInfo struct { + Digest *string `json:"Digest"` + Tag *string `json:"Tag"` + IsSigned *bool `json:"IsSigned"` + Layers []*LayerInfo `json:"Layers"` +} + type PackageInfo struct { Name *string `json:"Name"` InstalledVersion *string `json:"InstalledVersion"` FixedVersion *string `json:"FixedVersion"` } +type RepoInfo struct { + Manifests []*ManifestInfo `json:"Manifests"` +} + type TagInfo struct { Name *string `json:"Name"` Digest *string `json:"Digest"` diff --git a/pkg/extensions/search/resolver.go b/pkg/extensions/search/resolver.go index 86c051f9..783c0b91 100644 --- a/pkg/extensions/search/resolver.go +++ b/pkg/extensions/search/resolver.go @@ -62,6 +62,52 @@ func GetResolverConfig(log log.Logger, storeController storage.StoreController, } } +func (r *queryResolver) ExpandedRepoInfo(ctx context.Context, name string) (*RepoInfo, error) { + olu := common.NewOciLayoutUtils(r.storeController, r.log) + + repo, err := olu.GetExpandedRepoInfo(name) + if err != nil { + r.log.Error().Err(err).Msg("error getting repos") + + return &RepoInfo{}, err + } + + // repos type is of common deep copy this to search + repoInfo := &RepoInfo{} + + manifests := make([]*ManifestInfo, 0) + + for _, manifest := range repo.Manifests { + tag := manifest.Tag + + digest := manifest.Digest + + isSigned := manifest.IsSigned + + manifestInfo := &ManifestInfo{Tag: &tag, Digest: &digest, IsSigned: &isSigned} + + layers := make([]*LayerInfo, 0) + + for _, l := range manifest.Layers { + size := l.Size + + digest := l.Digest + + layerInfo := &LayerInfo{Digest: &digest, Size: &size} + + layers = append(layers, layerInfo) + } + + manifestInfo.Layers = layers + + manifests = append(manifests, manifestInfo) + } + + repoInfo.Manifests = manifests + + return repoInfo, nil +} + func (r *queryResolver) CVEListForImage(ctx context.Context, image string) (*CVEResultForImage, error) { trivyCtx := r.cveInfo.GetTrivyContext(image) diff --git a/pkg/extensions/search/schema.graphql b/pkg/extensions/search/schema.graphql index 28ea9d6c..7b10d794 100644 --- a/pkg/extensions/search/schema.graphql +++ b/pkg/extensions/search/schema.graphql @@ -50,10 +50,27 @@ type ImageInfo { Labels: String } +type RepoInfo { + Manifests: [ManifestInfo] +} + +type ManifestInfo { + Digest: String + Tag: String + IsSigned: Boolean + Layers: [LayerInfo] +} + +type LayerInfo { + Size: String # Int64 is not supported. + Digest: String +} + type Query { CVEListForImage(image: String!) :CVEResultForImage ImageListForCVE(id: String!) :[ImgResultForCVE] ImageListWithCVEFixed(id: String!, image: String!) :ImgResultForFixedCVE ImageListForDigest(id: String!) :[ImgResultForDigest] ImageListWithLatestTag:[ImageInfo] + ExpandedRepoInfo(repo: String!):RepoInfo }