From 388f47669d7c3fc2b83e6a8cf19be27b3d3c3918 Mon Sep 17 00:00:00 2001 From: Maxime Durand <72691393+Maxim-Durand@users.noreply.github.com> Date: Thu, 22 Feb 2024 10:56:18 +0100 Subject: [PATCH] refactor(report): Replacing `source_location` in `github` report when scanning an image (#5999) Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> --- pkg/report/github/github.go | 25 +++++++++++- pkg/report/github/github_test.go | 67 ++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/pkg/report/github/github.go b/pkg/report/github/github.go index 512a3dc9c528..e92d9921a2e6 100644 --- a/pkg/report/github/github.go +++ b/pkg/report/github/github.go @@ -105,8 +105,25 @@ func (w Writer) Write(ctx context.Context, report types.Report) error { manifest.Name = string(result.Type) // show path for language-specific packages only if result.Class == types.ClassLangPkg { - manifest.File = &File{ - SrcLocation: result.Target, + if report.ArtifactType == ftypes.ArtifactContainerImage { + // `RepoDigests` ~= /@sha256: + // `RepoTag` ~= /: + // By concatenating the hash from `RepoDigests` at the end of `RepoTag` we get all the information + imageReference := strings.Join(report.Metadata.RepoTags, ", ") + imageWithHash := strings.Join(report.Metadata.RepoDigests, ", ") + _, imageHash, found := strings.Cut(imageWithHash, "@") + if found { + imageReference += "@" + imageHash + } + // Replacing `source_location` in manifest by the image name, tag and hash + manifest.File = &File{ + SrcLocation: imageReference, + } + + } else { + manifest.File = &File{ + SrcLocation: result.Target, + } } } @@ -123,6 +140,10 @@ func (w Writer) Write(ctx context.Context, report types.Report) error { return xerrors.Errorf("unable to build purl for %s: %w", pkg.Name, err) } + if pkg.FilePath != "" { + githubPkg.Metadata = Metadata{"source_location": pkg.FilePath} + } + resolved[pkg.Name] = githubPkg } diff --git a/pkg/report/github/github_test.go b/pkg/report/github/github_test.go index ada2e8c84880..596fd8dd3862 100644 --- a/pkg/report/github/github_test.go +++ b/pkg/report/github/github_test.go @@ -164,6 +164,73 @@ func TestWriter_Write(t *testing.T) { }, }, }, + { + name: "pypi from image", + report: types.Report{ + SchemaVersion: 2, + ArtifactName: "fake_repo.azurecr.io/image_name", + ArtifactType: "container_image", + Metadata: types.Metadata{ + RepoDigests: []string{"fake_repo.azurecr.io/image_name@sha256:a7c92cdcb3d010f6edeb37ddcdbacab14981aa31e7f1140e0097dc1b8e834c49"}, + RepoTags: []string{"fake_repo.azurecr.io/image_name:latest"}, + }, + Results: types.Results{ + { + Target: "Python", + Class: "lang-pkgs", + Type: "python-pkg", + Packages: []ftypes.Package{ + { + Name: "jwcrypto", + Version: "0.7", + Licenses: []string{ + "LGPLv3+", + }, + Layer: ftypes.Layer{ + Digest: "sha256:ddc612ba4e74ea5633a93e19e7c32f61f5f230073b21a070302a61ef5eec5c50", + DiffID: "sha256:12935ef6ce21a266aef8df75d601cebf7e935edd01e9f19fab16ccb78fbb9a5e", + }, + FilePath: "opt/pyenv/versions/3.11.2/lib/python3.11/site-packages/jwcrypto-0.7.dist-info/METADATA", + }, + { + Name: "matplotlib", + Version: "3.5.3", + Licenses: []string{ + "PSF", + }, + Layer: ftypes.Layer{ + Digest: "sha256:ddc612ba4e74ea5633a93e19e7c32f61f5f230073b21a070302a61ef5eec5c50", + DiffID: "sha256:12935ef6ce21a266aef8df75d601cebf7e935edd01e9f19fab16ccb78fbb9a5e", + }, + FilePath: "opt/pyenv/versions/3.11.2/lib/python3.11/site-packages/matplotlib-3.5.3.dist-info/METADATA", + }, + }, + }, + }, + }, + want: map[string]github.Manifest{ + "Python": { + Name: "python-pkg", + File: &github.File{ + SrcLocation: "fake_repo.azurecr.io/image_name:latest@sha256:a7c92cdcb3d010f6edeb37ddcdbacab14981aa31e7f1140e0097dc1b8e834c49", + }, + Resolved: map[string]github.Package{ + "jwcrypto": { + PackageUrl: "pkg:pypi/jwcrypto@0.7", + Relationship: "direct", + Scope: "runtime", + Metadata: github.Metadata{"source_location": "opt/pyenv/versions/3.11.2/lib/python3.11/site-packages/jwcrypto-0.7.dist-info/METADATA"}, + }, + "matplotlib": { + PackageUrl: "pkg:pypi/matplotlib@3.5.3", + Relationship: "direct", + Scope: "runtime", + Metadata: github.Metadata{"source_location": "opt/pyenv/versions/3.11.2/lib/python3.11/site-packages/matplotlib-3.5.3.dist-info/METADATA"}, + }, + }, + }, + }, + }, } for _, tt := range tests {