diff --git a/integration/repo_test.go b/integration/repo_test.go index 3aa2baff521e..72edba8a562f 100644 --- a/integration/repo_test.go +++ b/integration/repo_test.go @@ -4,12 +4,13 @@ package integration import ( "fmt" - "github.com/stretchr/testify/assert" "os" "strings" "testing" - ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/stretchr/testify/assert" + + "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/types" ) @@ -379,7 +380,7 @@ func TestRepository(t *testing.T) { }, golden: "testdata/gomod-skip.json.golden", override: func(_ *testing.T, want, _ *types.Report) { - want.ArtifactType = ftypes.ArtifactFilesystem + want.ArtifactType = artifact.TypeFilesystem }, }, { @@ -393,7 +394,7 @@ func TestRepository(t *testing.T) { }, golden: "testdata/dockerfile-custom-policies.json.golden", override: func(_ *testing.T, want, got *types.Report) { - want.ArtifactType = ftypes.ArtifactFilesystem + want.ArtifactType = artifact.TypeFilesystem }, }, } diff --git a/integration/sbom_test.go b/integration/sbom_test.go index 428efe5cfec3..e3ee5b89cc3d 100644 --- a/integration/sbom_test.go +++ b/integration/sbom_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/types" ) @@ -37,7 +37,7 @@ func TestSBOM(t *testing.T) { golden: "testdata/centos-7.json.golden", override: func(t *testing.T, want, got *types.Report) { want.ArtifactName = "testdata/fixtures/sbom/centos-7-cyclonedx.json" - want.ArtifactType = ftypes.ArtifactCycloneDX + want.ArtifactType = artifact.TypeCycloneDX require.Len(t, got.Results, 1) want.Results[0].Target = "testdata/fixtures/sbom/centos-7-cyclonedx.json (centos 7.6.1810)" @@ -76,7 +76,7 @@ func TestSBOM(t *testing.T) { golden: "testdata/centos-7.json.golden", override: func(t *testing.T, want, got *types.Report) { want.ArtifactName = "testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl" - want.ArtifactType = ftypes.ArtifactCycloneDX + want.ArtifactType = artifact.TypeCycloneDX require.Len(t, got.Results, 1) want.Results[0].Target = "testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl (centos 7.6.1810)" @@ -97,7 +97,7 @@ func TestSBOM(t *testing.T) { golden: "testdata/centos-7.json.golden", override: func(t *testing.T, want, got *types.Report) { want.ArtifactName = "testdata/fixtures/sbom/centos-7-spdx.txt" - want.ArtifactType = ftypes.ArtifactSPDX + want.ArtifactType = artifact.TypeSPDX require.Len(t, got.Results, 1) want.Results[0].Target = "testdata/fixtures/sbom/centos-7-spdx.txt (centos 7.6.1810)" @@ -113,7 +113,7 @@ func TestSBOM(t *testing.T) { golden: "testdata/centos-7.json.golden", override: func(t *testing.T, want, got *types.Report) { want.ArtifactName = "testdata/fixtures/sbom/centos-7-spdx.json" - want.ArtifactType = ftypes.ArtifactSPDX + want.ArtifactType = artifact.TypeSPDX require.Len(t, got.Results, 1) want.Results[0].Target = "testdata/fixtures/sbom/centos-7-spdx.json (centos 7.6.1810)" diff --git a/integration/testdata/conda-spdx.json.golden b/integration/testdata/conda-spdx.json.golden index db81eb8abd13..f8a8778538c0 100644 --- a/integration/testdata/conda-spdx.json.golden +++ b/integration/testdata/conda-spdx.json.golden @@ -14,7 +14,7 @@ "packages": [ { "name": "openssl", - "SPDXID": "SPDXRef-Package-b8061a5279413d55", + "SPDXID": "SPDXRef-Package-32b6b37a6fa2e57f", "versionInfo": "1.1.1q", "supplier": "NOASSERTION", "downloadLocation": "NONE", @@ -38,7 +38,7 @@ }, { "name": "pip", - "SPDXID": "SPDXRef-Package-84198b3828050c11", + "SPDXID": "SPDXRef-Package-e260029d0b6fd07b", "versionInfo": "22.2.2", "supplier": "NOASSERTION", "downloadLocation": "NONE", @@ -103,22 +103,22 @@ }, { "spdxElementId": "SPDXRef-Filesystem-2e2426fd0f2580ef", - "relatedSpdxElement": "SPDXRef-Package-84198b3828050c11", + "relatedSpdxElement": "SPDXRef-Package-32b6b37a6fa2e57f", "relationshipType": "CONTAINS" }, { "spdxElementId": "SPDXRef-Filesystem-2e2426fd0f2580ef", - "relatedSpdxElement": "SPDXRef-Package-b8061a5279413d55", + "relatedSpdxElement": "SPDXRef-Package-e260029d0b6fd07b", "relationshipType": "CONTAINS" }, { - "spdxElementId": "SPDXRef-Package-84198b3828050c11", - "relatedSpdxElement": "SPDXRef-File-7eb62e2a3edddc0a", + "spdxElementId": "SPDXRef-Package-32b6b37a6fa2e57f", + "relatedSpdxElement": "SPDXRef-File-600e5e0110a84891", "relationshipType": "CONTAINS" }, { - "spdxElementId": "SPDXRef-Package-b8061a5279413d55", - "relatedSpdxElement": "SPDXRef-File-600e5e0110a84891", + "spdxElementId": "SPDXRef-Package-e260029d0b6fd07b", + "relatedSpdxElement": "SPDXRef-File-7eb62e2a3edddc0a", "relationshipType": "CONTAINS" } ] diff --git a/pkg/cloud/report/report.go b/pkg/cloud/report/report.go index 2b2f8f3f17ea..55d992fc505e 100644 --- a/pkg/cloud/report/report.go +++ b/pkg/cloud/report/report.go @@ -12,7 +12,7 @@ import ( "github.com/aquasecurity/tml" "github.com/aquasecurity/trivy/pkg/clock" cr "github.com/aquasecurity/trivy/pkg/compliance/report" - ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/flag" "github.com/aquasecurity/trivy/pkg/iac/scan" pkgReport "github.com/aquasecurity/trivy/pkg/report" @@ -97,7 +97,7 @@ func Write(ctx context.Context, rep *Report, opt flag.Options, fromCache bool) e base := types.Report{ CreatedAt: clock.Now(ctx), ArtifactName: rep.AccountID, - ArtifactType: ftypes.ArtifactAWSAccount, + ArtifactType: artifact.TypeAWSAccount, Results: filtered, } diff --git a/pkg/fanal/artifact/artifact.go b/pkg/fanal/artifact/artifact.go index b8245f585389..e431278f6fc2 100644 --- a/pkg/fanal/artifact/artifact.go +++ b/pkg/fanal/artifact/artifact.go @@ -4,10 +4,13 @@ import ( "context" "sort" + "github.com/google/go-containerregistry/pkg/v1" + "github.com/aquasecurity/trivy/pkg/fanal/analyzer" "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/fanal/walker" "github.com/aquasecurity/trivy/pkg/misconf" + "github.com/aquasecurity/trivy/pkg/sbom/core" ) type Option struct { @@ -72,6 +75,39 @@ func (o *Option) Sort() { } type Artifact interface { - Inspect(ctx context.Context) (reference types.ArtifactReference, err error) - Clean(reference types.ArtifactReference) error + Inspect(ctx context.Context) (reference Reference, err error) + Clean(reference Reference) error +} + +// Type represents a type of artifact +type Type string + +const ( + TypeContainerImage Type = "container_image" + TypeFilesystem Type = "filesystem" + TypeRepository Type = "repository" + TypeCycloneDX Type = "cyclonedx" + TypeSPDX Type = "spdx" + TypeAWSAccount Type = "aws_account" + TypeVM Type = "vm" +) + +// Reference represents a reference of container image, local filesystem and repository +type Reference struct { + Name string // image name, tar file name, directory or repository name + Type Type + ID string + BlobIDs []string + ImageMetadata ImageMetadata + + // SBOM + BOM *core.BOM +} + +type ImageMetadata struct { + ID string // image ID + DiffIDs []string // uncompressed layer IDs + RepoTags []string + RepoDigests []string + ConfigFile v1.ConfigFile } diff --git a/pkg/fanal/artifact/image/image.go b/pkg/fanal/artifact/image/image.go index b0749ad0d1ed..08b61de1b228 100644 --- a/pkg/fanal/artifact/image/image.go +++ b/pkg/fanal/artifact/image/image.go @@ -73,16 +73,16 @@ func NewArtifact(img types.Image, c cache.ArtifactCache, opt artifact.Option) (a }, nil } -func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) { +func (a Artifact) Inspect(ctx context.Context) (artifact.Reference, error) { imageID, err := a.image.ID() if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("unable to get the image ID: %w", err) + return artifact.Reference{}, xerrors.Errorf("unable to get the image ID: %w", err) } a.logger.Debug("Detected image ID", log.String("image_id", imageID)) configFile, err := a.image.ConfigFile() if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("unable to get the image's config file: %w", err) + return artifact.Reference{}, xerrors.Errorf("unable to get the image's config file: %w", err) } diffIDs := a.diffIDs(configFile) @@ -94,7 +94,7 @@ func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) return res, nil } else if !errors.Is(err, errNoSBOMFound) { // Fail on unexpected error, otherwise it falls into the usual scanning. - return types.ArtifactReference{}, xerrors.Errorf("remote SBOM fetching error: %w", err) + return artifact.Reference{}, xerrors.Errorf("remote SBOM fetching error: %w", err) } // Try to detect base layers. @@ -104,7 +104,7 @@ func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) // Convert image ID and layer IDs to cache keys imageKey, layerKeys, err := a.calcCacheKeys(imageID, diffIDs) if err != nil { - return types.ArtifactReference{}, err + return artifact.Reference{}, err } // Parse histories and extract a list of "created_by" @@ -112,7 +112,7 @@ func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) missingImage, missingLayers, err := a.cache.MissingBlobs(imageKey, layerKeys) if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("unable to get missing layers: %w", err) + return artifact.Reference{}, xerrors.Errorf("unable to get missing layers: %w", err) } missingImageKey := imageKey @@ -123,15 +123,15 @@ func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) } if err = a.inspect(ctx, missingImageKey, missingLayers, baseDiffIDs, layerKeyMap, configFile); err != nil { - return types.ArtifactReference{}, xerrors.Errorf("analyze error: %w", err) + return artifact.Reference{}, xerrors.Errorf("analyze error: %w", err) } - return types.ArtifactReference{ + return artifact.Reference{ Name: a.image.Name(), - Type: types.ArtifactContainerImage, + Type: artifact.TypeContainerImage, ID: imageKey, BlobIDs: layerKeys, - ImageMetadata: types.ImageMetadata{ + ImageMetadata: artifact.ImageMetadata{ ID: imageID, DiffIDs: diffIDs, RepoTags: a.image.RepoTags(), @@ -141,7 +141,7 @@ func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) }, nil } -func (Artifact) Clean(_ types.ArtifactReference) error { +func (Artifact) Clean(_ artifact.Reference) error { return nil } diff --git a/pkg/fanal/artifact/image/image_test.go b/pkg/fanal/artifact/image/image_test.go index fbcddef9ce4a..05fc6b229105 100644 --- a/pkg/fanal/artifact/image/image_test.go +++ b/pkg/fanal/artifact/image/image_test.go @@ -340,7 +340,7 @@ func TestArtifact_Inspect(t *testing.T) { missingBlobsExpectation cache.ArtifactCacheMissingBlobsExpectation putBlobExpectations []cache.ArtifactCachePutBlobExpectation putArtifactExpectations []cache.ArtifactCachePutArtifactExpectation - want types.ArtifactReference + want artifact.Reference wantErr string }{ { @@ -425,12 +425,12 @@ func TestArtifact_Inspect(t *testing.T) { }, }, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "../../test/testdata/alpine-311.tar.gz", - Type: types.ArtifactContainerImage, + Type: artifact.TypeContainerImage, ID: "sha256:c232b7d8ac8aa08aa767313d0b53084c4380d1c01a213a5971bdb039e6538313", BlobIDs: []string{"sha256:1fd280c63e1416a2261e76454caa19a5b77c6bddedd48309c9687c4fe72b34c0"}, - ImageMetadata: types.ImageMetadata{ + ImageMetadata: artifact.ImageMetadata{ ID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", DiffIDs: []string{ "sha256:beee9f30bc1f711043e78d4a2be0668955d4b761d587d6f60c2c8dc081efb203", @@ -1756,9 +1756,9 @@ func TestArtifact_Inspect(t *testing.T) { }, }, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "../../test/testdata/vuln-image.tar.gz", - Type: types.ArtifactContainerImage, + Type: artifact.TypeContainerImage, ID: "sha256:33f9415ed2cd5a9cef5d5144333619745b9ec0f851f0684dd45fa79c6b26a650", BlobIDs: []string{ "sha256:dd0a4f4754bf4590327be34f4266f63c92184352afadb72e4c9b162f76224000", @@ -1766,7 +1766,7 @@ func TestArtifact_Inspect(t *testing.T) { "sha256:b6be0de11c6090f71dea119f43dd360335643420058e317baffb089f0dff4001", "sha256:37c561c19b169f5f9832f4b0060bf74ebc8d1c9e01662ad4fa21c394da159440", }, - ImageMetadata: types.ImageMetadata{ + ImageMetadata: artifact.ImageMetadata{ ID: "sha256:58701fd185bda36cab0557bb6438661831267aa4a9e0b54211c4d5317a48aff4", DiffIDs: []string{ "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", @@ -1921,9 +1921,9 @@ func TestArtifact_Inspect(t *testing.T) { }, }, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "../../test/testdata/vuln-image.tar.gz", - Type: types.ArtifactContainerImage, + Type: artifact.TypeContainerImage, ID: "sha256:33f9415ed2cd5a9cef5d5144333619745b9ec0f851f0684dd45fa79c6b26a650", BlobIDs: []string{ "sha256:e1187118cdbe8893fc2fd4b345f813d195ee6aaeb4820d4576694199f8c10350", @@ -1931,7 +1931,7 @@ func TestArtifact_Inspect(t *testing.T) { "sha256:47adac0e28b12338e99dedbd7e8b0ef1f7aaa28e646f637ab2db8908b80704c8", "sha256:dd1082b33b17401fdc31bcbf60eaaecb9ce29e23956c50db6f34b2cc6cfa13c8", }, - ImageMetadata: types.ImageMetadata{ + ImageMetadata: artifact.ImageMetadata{ ID: "sha256:58701fd185bda36cab0557bb6438661831267aa4a9e0b54211c4d5317a48aff4", DiffIDs: []string{ "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", diff --git a/pkg/fanal/artifact/image/remote_sbom.go b/pkg/fanal/artifact/image/remote_sbom.go index 9bb609e64c3b..8a386546c07a 100644 --- a/pkg/fanal/artifact/image/remote_sbom.go +++ b/pkg/fanal/artifact/image/remote_sbom.go @@ -14,6 +14,7 @@ import ( "golang.org/x/xerrors" sbomatt "github.com/aquasecurity/trivy/pkg/attestation/sbom" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/fanal/artifact/sbom" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" @@ -24,9 +25,9 @@ import ( var errNoSBOMFound = xerrors.New("remote SBOM not found") -type inspectRemoteSBOM func(context.Context) (ftypes.ArtifactReference, error) +type inspectRemoteSBOM func(context.Context) (artifact.Reference, error) -func (a Artifact) retrieveRemoteSBOM(ctx context.Context) (ftypes.ArtifactReference, error) { +func (a Artifact) retrieveRemoteSBOM(ctx context.Context) (artifact.Reference, error) { for _, sbomSource := range a.artifactOption.SBOMSources { var inspect inspectRemoteSBOM switch sbomSource { @@ -45,27 +46,27 @@ func (a Artifact) retrieveRemoteSBOM(ctx context.Context) (ftypes.ArtifactRefere a.logger.Debug("No SBOM found in the source", log.String("source", sbomSource)) continue } else if err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("SBOM searching error: %w", err) + return artifact.Reference{}, xerrors.Errorf("SBOM searching error: %w", err) } return ref, nil } - return ftypes.ArtifactReference{}, errNoSBOMFound + return artifact.Reference{}, errNoSBOMFound } -func (a Artifact) inspectOCIReferrerSBOM(ctx context.Context) (ftypes.ArtifactReference, error) { +func (a Artifact) inspectOCIReferrerSBOM(ctx context.Context) (artifact.Reference, error) { digest, err := repoDigest(a.image, a.artifactOption.Insecure) if err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("repo digest error: %w", err) + return artifact.Reference{}, xerrors.Errorf("repo digest error: %w", err) } // Fetch referrers index, err := remote.Referrers(ctx, digest, a.artifactOption.ImageOption.RegistryOptions) if err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("unable to fetch referrers: %w", err) + return artifact.Reference{}, xerrors.Errorf("unable to fetch referrers: %w", err) } manifest, err := index.IndexManifest() if err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("unable to get manifest: %w", err) + return artifact.Reference{}, xerrors.Errorf("unable to get manifest: %w", err) } for _, m := range lo.FromPtr(manifest).Manifests { // Unsupported artifact type @@ -80,20 +81,20 @@ func (a Artifact) inspectOCIReferrerSBOM(ctx context.Context) (ftypes.ArtifactRe } return res, nil } - return ftypes.ArtifactReference{}, errNoSBOMFound + return artifact.Reference{}, errNoSBOMFound } -func (a Artifact) parseReferrer(ctx context.Context, repo string, desc v1.Descriptor) (ftypes.ArtifactReference, error) { +func (a Artifact) parseReferrer(ctx context.Context, repo string, desc v1.Descriptor) (artifact.Reference, error) { const fileName string = "referrer.sbom" repoName := fmt.Sprintf("%s@%s", repo, desc.Digest) referrer, err := oci.NewArtifact(repoName, true, a.artifactOption.ImageOption.RegistryOptions) if err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("OCI error: %w", err) + return artifact.Reference{}, xerrors.Errorf("OCI error: %w", err) } tmpDir, err := os.MkdirTemp("", "trivy-sbom-*") if err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("mkdir temp error: %w", err) + return artifact.Reference{}, xerrors.Errorf("mkdir temp error: %w", err) } defer os.RemoveAll(tmpDir) @@ -102,7 +103,7 @@ func (a Artifact) parseReferrer(ctx context.Context, repo string, desc v1.Descri MediaType: desc.ArtifactType, Filename: fileName, }); err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("SBOM download error: %w", err) + return artifact.Reference{}, xerrors.Errorf("SBOM download error: %w", err) } res, err := a.inspectSBOMFile(ctx, filepath.Join(tmpDir, fileName)) @@ -116,35 +117,35 @@ func (a Artifact) parseReferrer(ctx context.Context, repo string, desc v1.Descri return res, nil } -func (a Artifact) inspectRekorSBOMAttestation(ctx context.Context) (ftypes.ArtifactReference, error) { +func (a Artifact) inspectRekorSBOMAttestation(ctx context.Context) (artifact.Reference, error) { digest, err := repoDigest(a.image, a.artifactOption.Insecure) if err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("repo digest error: %w", err) + return artifact.Reference{}, xerrors.Errorf("repo digest error: %w", err) } client, err := sbomatt.NewRekor(a.artifactOption.RekorURL) if err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("failed to create rekor client: %w", err) + return artifact.Reference{}, xerrors.Errorf("failed to create rekor client: %w", err) } raw, err := client.RetrieveSBOM(ctx, digest.DigestStr()) if errors.Is(err, sbomatt.ErrNoSBOMAttestation) { - return ftypes.ArtifactReference{}, errNoSBOMFound + return artifact.Reference{}, errNoSBOMFound } else if err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("failed to retrieve SBOM attestation: %w", err) + return artifact.Reference{}, xerrors.Errorf("failed to retrieve SBOM attestation: %w", err) } f, err := os.CreateTemp("", "sbom-*") if err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("failed to create a temporary file: %w", err) + return artifact.Reference{}, xerrors.Errorf("failed to create a temporary file: %w", err) } defer os.Remove(f.Name()) if _, err = f.Write(raw); err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("copy error: %w", err) + return artifact.Reference{}, xerrors.Errorf("copy error: %w", err) } if err = f.Close(); err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("failed to close %s: %w", f.Name(), err) + return artifact.Reference{}, xerrors.Errorf("failed to close %s: %w", f.Name(), err) } res, err := a.inspectSBOMFile(ctx, f.Name()) if err != nil { @@ -158,15 +159,15 @@ func (a Artifact) inspectRekorSBOMAttestation(ctx context.Context) (ftypes.Artif return res, nil } -func (a Artifact) inspectSBOMFile(ctx context.Context, filePath string) (ftypes.ArtifactReference, error) { +func (a Artifact) inspectSBOMFile(ctx context.Context, filePath string) (artifact.Reference, error) { ar, err := sbom.NewArtifact(filePath, a.cache, a.artifactOption) if err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("failed to new artifact: %w", err) + return artifact.Reference{}, xerrors.Errorf("failed to new artifact: %w", err) } results, err := ar.Inspect(ctx) if err != nil { - return ftypes.ArtifactReference{}, xerrors.Errorf("failed to inspect: %w", err) + return artifact.Reference{}, xerrors.Errorf("failed to inspect: %w", err) } results.Name = a.image.Name() diff --git a/pkg/fanal/artifact/image/remote_sbom_test.go b/pkg/fanal/artifact/image/remote_sbom_test.go index b38bdc5c6dc5..2b58d2fdb8a3 100644 --- a/pkg/fanal/artifact/image/remote_sbom_test.go +++ b/pkg/fanal/artifact/image/remote_sbom_test.go @@ -56,7 +56,7 @@ func TestArtifact_InspectRekorAttestation(t *testing.T) { fields fields artifactOpt artifact.Option putBlobExpectations []cache.ArtifactCachePutBlobExpectation - want types.ArtifactReference + want artifact.Reference wantErr string }{ { @@ -117,9 +117,9 @@ func TestArtifact_InspectRekorAttestation(t *testing.T) { artifactOpt: artifact.Option{ SBOMSources: []string{"rekor"}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "test/image:10", - Type: types.ArtifactCycloneDX, + Type: artifact.TypeCycloneDX, ID: "sha256:066b9998617ffb7dfe0a3219ac5c3efc1008a6223606fcf474e7d5c965e4e8da", BlobIDs: []string{ "sha256:066b9998617ffb7dfe0a3219ac5c3efc1008a6223606fcf474e7d5c965e4e8da", @@ -206,7 +206,7 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) { fields fields artifactOpt artifact.Option putBlobExpectations []cache.ArtifactCachePutBlobExpectation - want types.ArtifactReference + want artifact.Reference wantErr string }{ { @@ -265,9 +265,9 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) { }, }, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: registry + "/test/image:10", - Type: types.ArtifactCycloneDX, + Type: artifact.TypeCycloneDX, ID: "sha256:a06ed679a3289fba254040e1ce8f3467fadcc454ee3d0d4720f6978065f56684", BlobIDs: []string{ "sha256:a06ed679a3289fba254040e1ce8f3467fadcc454ee3d0d4720f6978065f56684", diff --git a/pkg/fanal/artifact/local/fs.go b/pkg/fanal/artifact/local/fs.go index 5896196c0e48..b807db2c6733 100644 --- a/pkg/fanal/artifact/local/fs.go +++ b/pkg/fanal/artifact/local/fs.go @@ -68,7 +68,7 @@ func NewArtifact(rootPath string, c cache.ArtifactCache, w Walker, opt artifact. }, nil } -func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) { +func (a Artifact) Inspect(ctx context.Context) (artifact.Reference, error) { var wg sync.WaitGroup result := analyzer.NewAnalysisResult() limit := semaphore.New(a.artifactOption.Parallel) @@ -80,7 +80,7 @@ func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) // Prepare filesystem for post analysis composite, err := a.analyzer.PostAnalyzerFS() if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("failed to prepare filesystem for post analysis: %w", err) + return artifact.Reference{}, xerrors.Errorf("failed to prepare filesystem for post analysis: %w", err) } err = a.walker.Walk(a.rootPath, a.artifactOption.WalkerOption, func(filePath string, info os.FileInfo, opener analyzer.Opener) error { @@ -110,7 +110,7 @@ func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) return nil }) if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("walk filesystem: %w", err) + return artifact.Reference{}, xerrors.Errorf("walk filesystem: %w", err) } // Wait for all the goroutine to finish. @@ -118,7 +118,7 @@ func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) // Post-analysis if err = a.analyzer.PostAnalyze(ctx, composite, result, opts); err != nil { - return types.ArtifactReference{}, xerrors.Errorf("post analysis error: %w", err) + return artifact.Reference{}, xerrors.Errorf("post analysis error: %w", err) } // Sort the analysis result for consistent results @@ -137,16 +137,16 @@ func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) } if err = a.handlerManager.PostHandle(ctx, result, &blobInfo); err != nil { - return types.ArtifactReference{}, xerrors.Errorf("failed to call hooks: %w", err) + return artifact.Reference{}, xerrors.Errorf("failed to call hooks: %w", err) } cacheKey, err := a.calcCacheKey(blobInfo) if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("failed to calculate a cache key: %w", err) + return artifact.Reference{}, xerrors.Errorf("failed to calculate a cache key: %w", err) } if err = a.cache.PutBlob(cacheKey, blobInfo); err != nil { - return types.ArtifactReference{}, xerrors.Errorf("failed to store blob (%s) in cache: %w", cacheKey, err) + return artifact.Reference{}, xerrors.Errorf("failed to store blob (%s) in cache: %w", cacheKey, err) } // get hostname @@ -159,15 +159,15 @@ func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) hostName = filepath.ToSlash(a.rootPath) } - return types.ArtifactReference{ + return artifact.Reference{ Name: hostName, - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: cacheKey, // use a cache key as pseudo artifact ID BlobIDs: []string{cacheKey}, }, nil } -func (a Artifact) Clean(reference types.ArtifactReference) error { +func (a Artifact) Clean(reference artifact.Reference) error { return a.cache.DeleteBlobs(reference.BlobIDs) } diff --git a/pkg/fanal/artifact/local/fs_test.go b/pkg/fanal/artifact/local/fs_test.go index f230cb1340fc..176a53797616 100644 --- a/pkg/fanal/artifact/local/fs_test.go +++ b/pkg/fanal/artifact/local/fs_test.go @@ -36,7 +36,7 @@ func TestArtifact_Inspect(t *testing.T) { disabledAnalyzers []analyzer.Type disabledHandlers []types.HandlerType putBlobExpectation cache.ArtifactCachePutBlobExpectation - want types.ArtifactReference + want artifact.Reference wantErr string }{ { @@ -78,9 +78,9 @@ func TestArtifact_Inspect(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "host", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:afc2bc421aac8c61d89d4dd1c1865efb5441e3877c8a4c919232729d7c574dab", BlobIDs: []string{ "sha256:afc2bc421aac8c61d89d4dd1c1865efb5441e3877c8a4c919232729d7c574dab", @@ -108,9 +108,9 @@ func TestArtifact_Inspect(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "host", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:7db98974b2231d3e25f4890008c4d42f6f26a7da5a8aba99e954dec97f050bd6", BlobIDs: []string{ "sha256:7db98974b2231d3e25f4890008c4d42f6f26a7da5a8aba99e954dec97f050bd6", @@ -193,9 +193,9 @@ func TestArtifact_Inspect(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/requirements.txt", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:9e999fcf6fd571e175601fb7cc0da28f0d7960e26eab67dad93152e0bebf21ca", BlobIDs: []string{ "sha256:9e999fcf6fd571e175601fb7cc0da28f0d7960e26eab67dad93152e0bebf21ca", @@ -228,9 +228,9 @@ func TestArtifact_Inspect(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/requirements.txt", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:9e999fcf6fd571e175601fb7cc0da28f0d7960e26eab67dad93152e0bebf21ca", BlobIDs: []string{ "sha256:9e999fcf6fd571e175601fb7cc0da28f0d7960e26eab67dad93152e0bebf21ca", @@ -279,7 +279,7 @@ func TestTerraformMisconfigurationScan(t *testing.T) { fields fields putBlobExpectation cache.ArtifactCachePutBlobExpectation artifactOpt artifact.Option - want types.ArtifactReference + want artifact.Reference }{ { name: "single failure", @@ -325,9 +325,9 @@ func TestTerraformMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/terraform/single-failure", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:1a6ce0acc3b57eb6c830c96fcd868fec1eb4d3b57ad51e481c76d85f22870a65", BlobIDs: []string{ "sha256:1a6ce0acc3b57eb6c830c96fcd868fec1eb4d3b57ad51e481c76d85f22870a65", @@ -410,9 +410,9 @@ func TestTerraformMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/terraform/multiple-failures", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:afc20cf0fc99c62bbc79b00cb9fbc70ba7ee76c946a6d560639ba9279344787d", BlobIDs: []string{ "sha256:afc20cf0fc99c62bbc79b00cb9fbc70ba7ee76c946a6d560639ba9279344787d", @@ -440,9 +440,9 @@ func TestTerraformMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/terraform/no-results", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:1827b6a0b0a17e0d623a2045e9d9c331ef613390eda2fed823969ee0dd730257", BlobIDs: []string{ "sha256:1827b6a0b0a17e0d623a2045e9d9c331ef613390eda2fed823969ee0dd730257", @@ -489,9 +489,9 @@ func TestTerraformMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/terraform/passed", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:eec58ef10d1b04df4af76b2472e615f8c27e253a16f90d7542670a7001d88915", BlobIDs: []string{ "sha256:eec58ef10d1b04df4af76b2472e615f8c27e253a16f90d7542670a7001d88915", @@ -555,9 +555,9 @@ func TestTerraformMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/terraform/busted-relative-paths/child/main.tf", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:8db34d644bfb98077180616caeab0b41a26d9029a47a23d4b36e1d6e45584919", BlobIDs: []string{ "sha256:8db34d644bfb98077180616caeab0b41a26d9029a47a23d4b36e1d6e45584919", @@ -605,9 +605,9 @@ func TestTerraformMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/terraform/tfvar-outside/tf", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:eec58ef10d1b04df4af76b2472e615f8c27e253a16f90d7542670a7001d88915", BlobIDs: []string{ "sha256:eec58ef10d1b04df4af76b2472e615f8c27e253a16f90d7542670a7001d88915", @@ -695,9 +695,9 @@ func TestTerraformMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/terraform/relative-paths/child", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:f13b89447db61be1c1e4099ef18aec7272091f8f2d3581643a9d1fabc74eda83", BlobIDs: []string{ "sha256:f13b89447db61be1c1e4099ef18aec7272091f8f2d3581643a9d1fabc74eda83", @@ -776,7 +776,7 @@ func TestTerraformPlanSnapshotMisconfScan(t *testing.T) { name string fields fields putBlobExpectation cache.ArtifactCachePutBlobExpectation - want types.ArtifactReference + want artifact.Reference }{ { name: "single failure", @@ -814,9 +814,9 @@ func TestTerraformPlanSnapshotMisconfScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/terraformplan/snapshots/single-failure", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:732c38451bde877a94d1ff5b6f2019655bed04fd24b1169de195eeee1199045e", BlobIDs: []string{ "sha256:732c38451bde877a94d1ff5b6f2019655bed04fd24b1169de195eeee1199045e", @@ -890,9 +890,9 @@ func TestTerraformPlanSnapshotMisconfScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/terraformplan/snapshots/multiple-failures", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:752c0b470adfcfe7e21892cf4c6fc3bc28dba873c9c1696f40b71b7a51ad7231", BlobIDs: []string{ "sha256:752c0b470adfcfe7e21892cf4c6fc3bc28dba873c9c1696f40b71b7a51ad7231", @@ -930,9 +930,9 @@ func TestTerraformPlanSnapshotMisconfScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/terraformplan/snapshots/passed", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:8947704a08f54ab1df32cd905d6bca72edf1785a42702968bafa331172da7176", BlobIDs: []string{ "sha256:8947704a08f54ab1df32cd905d6bca72edf1785a42702968bafa331172da7176", @@ -990,7 +990,7 @@ func TestCloudFormationMisconfigurationScan(t *testing.T) { fields fields putBlobExpectation cache.ArtifactCachePutBlobExpectation artifactOpt artifact.Option - want types.ArtifactReference + want artifact.Reference }{ { name: "single failure", @@ -1045,9 +1045,9 @@ func TestCloudFormationMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/cloudformation/single-failure/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:889a94522970c6e55f1f7543914b2f0131f79f9c4526445fb95309f64a9947d7", BlobIDs: []string{ "sha256:889a94522970c6e55f1f7543914b2f0131f79f9c4526445fb95309f64a9947d7", @@ -1129,9 +1129,9 @@ func TestCloudFormationMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/cloudformation/multiple-failures/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:17c9c72a759856445e6d3847b2d5ed90c3bad3e4ee50cea0c812ef53c179f8ca", BlobIDs: []string{ "sha256:17c9c72a759856445e6d3847b2d5ed90c3bad3e4ee50cea0c812ef53c179f8ca", @@ -1161,9 +1161,9 @@ func TestCloudFormationMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/cloudformation/no-results/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:26c76a2cb55cb0ef2c3a2dd79e237bddb508ca2c4cefdb103698a1972c8a9c2d", BlobIDs: []string{ "sha256:26c76a2cb55cb0ef2c3a2dd79e237bddb508ca2c4cefdb103698a1972c8a9c2d", @@ -1219,9 +1219,9 @@ func TestCloudFormationMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/cloudformation/params/code/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:267b572211115db6a2a4484a02317fbb6d4f050da0e95b1db4243d49889483de", BlobIDs: []string{ "sha256:267b572211115db6a2a4484a02317fbb6d4f050da0e95b1db4243d49889483de", @@ -1277,9 +1277,9 @@ func TestCloudFormationMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/cloudformation/passed/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:8ca92725ce2f47b7ffb1b0a9e0359d59ac2b3b3f517ba42f66a859436057e54a", BlobIDs: []string{ "sha256:8ca92725ce2f47b7ffb1b0a9e0359d59ac2b3b3f517ba42f66a859436057e54a", @@ -1314,7 +1314,7 @@ func TestDockerfileMisconfigurationScan(t *testing.T) { fields fields putBlobExpectation cache.ArtifactCachePutBlobExpectation artifactOpt artifact.Option - want types.ArtifactReference + want artifact.Reference }{ { name: "single failure", @@ -1365,9 +1365,9 @@ func TestDockerfileMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/dockerfile/single-failure/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:627cbf451ec7929dfe5151dfe0e2305ed855906bf79136f198528a0cc3f6e4f9", BlobIDs: []string{ "sha256:627cbf451ec7929dfe5151dfe0e2305ed855906bf79136f198528a0cc3f6e4f9", @@ -1423,9 +1423,9 @@ func TestDockerfileMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/dockerfile/multiple-failures/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:627cbf451ec7929dfe5151dfe0e2305ed855906bf79136f198528a0cc3f6e4f9", BlobIDs: []string{ "sha256:627cbf451ec7929dfe5151dfe0e2305ed855906bf79136f198528a0cc3f6e4f9", @@ -1453,9 +1453,9 @@ func TestDockerfileMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/dockerfile/no-results/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:26c76a2cb55cb0ef2c3a2dd79e237bddb508ca2c4cefdb103698a1972c8a9c2d", BlobIDs: []string{ "sha256:26c76a2cb55cb0ef2c3a2dd79e237bddb508ca2c4cefdb103698a1972c8a9c2d", @@ -1513,9 +1513,9 @@ func TestDockerfileMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/dockerfile/passed/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:4cc7f6bba417cc65c5391bc9c07fd1e205e21bdec87b271889433af18be1e454", BlobIDs: []string{ "sha256:4cc7f6bba417cc65c5391bc9c07fd1e205e21bdec87b271889433af18be1e454", @@ -1549,7 +1549,7 @@ func TestKubernetesMisconfigurationScan(t *testing.T) { fields fields putBlobExpectation cache.ArtifactCachePutBlobExpectation artifactOpt artifact.Option - want types.ArtifactReference + want artifact.Reference }{ { name: "single failure", @@ -1605,9 +1605,9 @@ func TestKubernetesMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/kubernetes/single-failure/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:d5ca0b4e96aaaeafa424a2250db6297a5182cb6ca5db49bc1ff11790f6cdbee9", BlobIDs: []string{ "sha256:d5ca0b4e96aaaeafa424a2250db6297a5182cb6ca5db49bc1ff11790f6cdbee9", @@ -1691,9 +1691,9 @@ func TestKubernetesMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/kubernetes/multiple-failures/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:eef9fff2fe8f5c4a123c018b4f91db25d9676e7d171a3a683c2fbfbbbe82fa54", BlobIDs: []string{ "sha256:eef9fff2fe8f5c4a123c018b4f91db25d9676e7d171a3a683c2fbfbbbe82fa54", @@ -1721,9 +1721,9 @@ func TestKubernetesMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/kubernetes/no-results/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:2b54cf33feaa1fe1f5bf223f873ca6c3f7c3693b0bb3b0ce9e2e7fd79cd37b5a", BlobIDs: []string{ "sha256:2b54cf33feaa1fe1f5bf223f873ca6c3f7c3693b0bb3b0ce9e2e7fd79cd37b5a", @@ -1781,9 +1781,9 @@ func TestKubernetesMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/kubernetes/passed/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:dc7a0fd3ea2f13b0ea05f4e517a16e602b0fc17fbd72aa5e34107ef12a91a30b", BlobIDs: []string{ "sha256:dc7a0fd3ea2f13b0ea05f4e517a16e602b0fc17fbd72aa5e34107ef12a91a30b", @@ -1817,7 +1817,7 @@ func TestAzureARMMisconfigurationScan(t *testing.T) { fields fields putBlobExpectation cache.ArtifactCachePutBlobExpectation artifactOpt artifact.Option - want types.ArtifactReference + want artifact.Reference }{ { name: "single failure", @@ -1870,9 +1870,9 @@ func TestAzureARMMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/azurearm/single-failure/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:c1a8bfd544b9041ad194382cc42b54289f70966d061ef501b267aec8fd07c5df", BlobIDs: []string{ "sha256:c1a8bfd544b9041ad194382cc42b54289f70966d061ef501b267aec8fd07c5df", @@ -1952,9 +1952,9 @@ func TestAzureARMMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/azurearm/multiple-failures/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:75bf0e88f8d2857be90fb8d10a350c04c1532ba7f510e1eb404a8bae30ce97d8", BlobIDs: []string{ "sha256:75bf0e88f8d2857be90fb8d10a350c04c1532ba7f510e1eb404a8bae30ce97d8", @@ -1982,9 +1982,9 @@ func TestAzureARMMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/azurearm/no-results/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:26c76a2cb55cb0ef2c3a2dd79e237bddb508ca2c4cefdb103698a1972c8a9c2d", BlobIDs: []string{ "sha256:26c76a2cb55cb0ef2c3a2dd79e237bddb508ca2c4cefdb103698a1972c8a9c2d", @@ -2038,9 +2038,9 @@ func TestAzureARMMisconfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/azurearm/passed/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, ID: "sha256:b9ba7c4eafec405c8b6998dbb98ee1c7f7830caf8487fd1461433ff82d8779e9", BlobIDs: []string{ "sha256:b9ba7c4eafec405c8b6998dbb98ee1c7f7830caf8487fd1461433ff82d8779e9", @@ -2074,7 +2074,7 @@ func TestMixedConfigurationScan(t *testing.T) { fields fields putBlobExpectation cache.ArtifactCachePutBlobExpectation artifactOpt artifact.Option - want types.ArtifactReference + want artifact.Reference }{ { name: "single failure each within terraform and cloudformation", @@ -2157,9 +2157,9 @@ func TestMixedConfigurationScan(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "testdata/misconfig/mixed/src", - Type: types.ArtifactFilesystem, + Type: artifact.TypeFilesystem, }, }, } diff --git a/pkg/fanal/artifact/mock_artifact.go b/pkg/fanal/artifact/mock_artifact.go index d17a15d46089..edfe12514659 100644 --- a/pkg/fanal/artifact/mock_artifact.go +++ b/pkg/fanal/artifact/mock_artifact.go @@ -6,8 +6,6 @@ import ( context "context" mock "github.com/stretchr/testify/mock" - - types "github.com/aquasecurity/trivy/pkg/fanal/types" ) // MockArtifact is an autogenerated mock type for the Artifact type @@ -16,7 +14,7 @@ type MockArtifact struct { } type ArtifactCleanArgs struct { - Reference types.ArtifactReference + Reference Reference ReferenceAnything bool } @@ -46,7 +44,7 @@ func (_m *MockArtifact) ApplyCleanExpectations(expectations []ArtifactCleanExpec } // Clean provides a mock function with given fields: reference -func (_m *MockArtifact) Clean(reference types.ArtifactReference) error { +func (_m *MockArtifact) Clean(reference Reference) error { return nil } @@ -56,7 +54,7 @@ type ArtifactInspectArgs struct { } type ArtifactInspectReturns struct { - Reference types.ArtifactReference + Reference Reference Err error } @@ -82,14 +80,14 @@ func (_m *MockArtifact) ApplyInspectExpectations(expectations []ArtifactInspectE } // Inspect provides a mock function with given fields: ctx -func (_m *MockArtifact) Inspect(ctx context.Context) (types.ArtifactReference, error) { +func (_m *MockArtifact) Inspect(ctx context.Context) (Reference, error) { ret := _m.Called(ctx) - var r0 types.ArtifactReference - if rf, ok := ret.Get(0).(func(context.Context) types.ArtifactReference); ok { + var r0 Reference + if rf, ok := ret.Get(0).(func(context.Context) Reference); ok { r0 = rf(ctx) } else { - r0 = ret.Get(0).(types.ArtifactReference) + r0 = ret.Get(0).(Reference) } var r1 error diff --git a/pkg/fanal/artifact/repo/git.go b/pkg/fanal/artifact/repo/git.go index 977c75d71bb7..4ce1c990c925 100644 --- a/pkg/fanal/artifact/repo/git.go +++ b/pkg/fanal/artifact/repo/git.go @@ -15,7 +15,6 @@ import ( "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/fanal/artifact/local" "github.com/aquasecurity/trivy/pkg/fanal/cache" - "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/fanal/walker" ) @@ -62,21 +61,21 @@ func NewArtifact(target string, c cache.ArtifactCache, w Walker, artifactOpt art return nil, cleanup, errs } -func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) { +func (a Artifact) Inspect(ctx context.Context) (artifact.Reference, error) { ref, err := a.local.Inspect(ctx) if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("remote repository error: %w", err) + return artifact.Reference{}, xerrors.Errorf("remote repository error: %w", err) } if a.url != "" { ref.Name = a.url } - ref.Type = types.ArtifactRepository + ref.Type = artifact.TypeRepository return ref, nil } -func (Artifact) Clean(_ types.ArtifactReference) error { +func (Artifact) Clean(_ artifact.Reference) error { return nil } diff --git a/pkg/fanal/artifact/repo/git_test.go b/pkg/fanal/artifact/repo/git_test.go index de484e64d221..0e7aadd411a9 100644 --- a/pkg/fanal/artifact/repo/git_test.go +++ b/pkg/fanal/artifact/repo/git_test.go @@ -12,12 +12,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/aquasecurity/trivy/pkg/fanal/artifact" - "github.com/aquasecurity/trivy/pkg/fanal/cache" - "github.com/aquasecurity/trivy/pkg/fanal/types" - _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/config/all" _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/secret" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" + "github.com/aquasecurity/trivy/pkg/fanal/cache" ) func setupGitServer() (*httptest.Server, error) { @@ -186,15 +184,15 @@ func TestArtifact_Inspect(t *testing.T) { tests := []struct { name string rawurl string - want types.ArtifactReference + want artifact.Reference wantErr bool }{ { name: "happy path", rawurl: ts.URL + "/test.git", - want: types.ArtifactReference{ + want: artifact.Reference{ Name: ts.URL + "/test.git", - Type: types.ArtifactRepository, + Type: artifact.TypeRepository, ID: "sha256:6a89d4fcd50f840a79da64523c255da80171acd3d286df2acc60056c778d9304", BlobIDs: []string{ "sha256:6a89d4fcd50f840a79da64523c255da80171acd3d286df2acc60056c778d9304", diff --git a/pkg/fanal/artifact/sbom/sbom.go b/pkg/fanal/artifact/sbom/sbom.go index 90eed8c89e1b..979c5c5a8517 100644 --- a/pkg/fanal/artifact/sbom/sbom.go +++ b/pkg/fanal/artifact/sbom/sbom.go @@ -37,23 +37,23 @@ func NewArtifact(filePath string, c cache.ArtifactCache, opt artifact.Option) (a }, nil } -func (a Artifact) Inspect(_ context.Context) (types.ArtifactReference, error) { +func (a Artifact) Inspect(_ context.Context) (artifact.Reference, error) { f, err := os.Open(a.filePath) if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("failed to open sbom file error: %w", err) + return artifact.Reference{}, xerrors.Errorf("failed to open sbom file error: %w", err) } defer f.Close() // Format auto-detection format, err := sbom.DetectFormat(f) if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("failed to detect SBOM format: %w", err) + return artifact.Reference{}, xerrors.Errorf("failed to detect SBOM format: %w", err) } log.Info("Detected SBOM format", log.String("format", string(format))) bom, err := sbom.Decode(f, format) if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("SBOM decode error: %w", err) + return artifact.Reference{}, xerrors.Errorf("SBOM decode error: %w", err) } blobInfo := types.BlobInfo{ @@ -65,23 +65,23 @@ func (a Artifact) Inspect(_ context.Context) (types.ArtifactReference, error) { cacheKey, err := a.calcCacheKey(blobInfo) if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("failed to calculate a cache key: %w", err) + return artifact.Reference{}, xerrors.Errorf("failed to calculate a cache key: %w", err) } if err = a.cache.PutBlob(cacheKey, blobInfo); err != nil { - return types.ArtifactReference{}, xerrors.Errorf("failed to store blob (%s) in cache: %w", cacheKey, err) + return artifact.Reference{}, xerrors.Errorf("failed to store blob (%s) in cache: %w", cacheKey, err) } - var artifactType types.ArtifactType + var artifactType artifact.Type switch format { case sbom.FormatCycloneDXJSON, sbom.FormatCycloneDXXML, sbom.FormatAttestCycloneDXJSON, sbom.FormatLegacyCosignAttestCycloneDXJSON: - artifactType = types.ArtifactCycloneDX + artifactType = artifact.TypeCycloneDX case sbom.FormatSPDXTV, sbom.FormatSPDXJSON: - artifactType = types.ArtifactSPDX + artifactType = artifact.TypeSPDX } - return types.ArtifactReference{ + return artifact.Reference{ Name: a.filePath, Type: artifactType, ID: cacheKey, // use a cache key as pseudo artifact ID @@ -92,7 +92,7 @@ func (a Artifact) Inspect(_ context.Context) (types.ArtifactReference, error) { }, nil } -func (a Artifact) Clean(reference types.ArtifactReference) error { +func (a Artifact) Clean(reference artifact.Reference) error { return a.cache.DeleteBlobs(reference.BlobIDs) } diff --git a/pkg/fanal/artifact/sbom/sbom_test.go b/pkg/fanal/artifact/sbom/sbom_test.go index 11ddfdad781b..7355c0c75abe 100644 --- a/pkg/fanal/artifact/sbom/sbom_test.go +++ b/pkg/fanal/artifact/sbom/sbom_test.go @@ -22,7 +22,7 @@ func TestArtifact_Inspect(t *testing.T) { name string filePath string putBlobExpectation cache.ArtifactCachePutBlobExpectation - want types.ArtifactReference + want artifact.Reference wantErr []string }{ { @@ -188,9 +188,9 @@ func TestArtifact_Inspect(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: filepath.Join("testdata", "bom.json"), - Type: types.ArtifactCycloneDX, + Type: artifact.TypeCycloneDX, ID: "sha256:76bc49ae239d24c6a122e730bafb9d5295d0af380492aeb92a3bf34bea3a14ca", BlobIDs: []string{ "sha256:76bc49ae239d24c6a122e730bafb9d5295d0af380492aeb92a3bf34bea3a14ca", @@ -360,9 +360,9 @@ func TestArtifact_Inspect(t *testing.T) { }, Returns: cache.ArtifactCachePutBlobReturns{}, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: filepath.Join("testdata", "sbom.cdx.intoto.jsonl"), - Type: types.ArtifactCycloneDX, + Type: artifact.TypeCycloneDX, ID: "sha256:76bc49ae239d24c6a122e730bafb9d5295d0af380492aeb92a3bf34bea3a14ca", BlobIDs: []string{ "sha256:76bc49ae239d24c6a122e730bafb9d5295d0af380492aeb92a3bf34bea3a14ca", diff --git a/pkg/fanal/artifact/vm/ami.go b/pkg/fanal/artifact/vm/ami.go index 791c41d52896..23b72990ae74 100644 --- a/pkg/fanal/artifact/vm/ami.go +++ b/pkg/fanal/artifact/vm/ami.go @@ -8,7 +8,7 @@ import ( "golang.org/x/xerrors" "github.com/aquasecurity/trivy/pkg/cloud/aws/config" - "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/log" ) @@ -55,10 +55,10 @@ func newAMI(imageID string, storage Storage, region, endpoint string) (*AMI, err return nil, xerrors.New("no snapshot found") } -func (a *AMI) Inspect(ctx context.Context) (types.ArtifactReference, error) { +func (a *AMI) Inspect(ctx context.Context) (artifact.Reference, error) { ref, err := a.EBS.Inspect(ctx) if err != nil { - return types.ArtifactReference{}, err + return artifact.Reference{}, err } ref.Name = a.imageID return ref, nil diff --git a/pkg/fanal/artifact/vm/ebs.go b/pkg/fanal/artifact/vm/ebs.go index d9881edf193a..64e1cc6a6b5a 100644 --- a/pkg/fanal/artifact/vm/ebs.go +++ b/pkg/fanal/artifact/vm/ebs.go @@ -9,8 +9,8 @@ import ( "golang.org/x/xerrors" "github.com/aquasecurity/trivy/pkg/cloud/aws/config" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/fanal/cache" - "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" ) @@ -40,21 +40,21 @@ func newEBS(snapshotID string, vm Storage, region, endpoint string) (*EBS, error }, nil } -func (a *EBS) Inspect(ctx context.Context) (types.ArtifactReference, error) { +func (a *EBS) Inspect(ctx context.Context) (artifact.Reference, error) { sr, err := a.openEBS(ctx) if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("EBS open error: %w", err) + return artifact.Reference{}, xerrors.Errorf("EBS open error: %w", err) } cacheKey, err := a.calcCacheKey(a.snapshotID) if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("cache key calculation error: %w", err) + return artifact.Reference{}, xerrors.Errorf("cache key calculation error: %w", err) } if a.hasCache(cacheKey) { - return types.ArtifactReference{ + return artifact.Reference{ Name: a.snapshotID, - Type: types.ArtifactVM, + Type: artifact.TypeVM, ID: cacheKey, // use a cache key as pseudo artifact ID BlobIDs: []string{cacheKey}, }, nil @@ -62,16 +62,16 @@ func (a *EBS) Inspect(ctx context.Context) (types.ArtifactReference, error) { blobInfo, err := a.Analyze(ctx, sr) if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("inspection error: %w", err) + return artifact.Reference{}, xerrors.Errorf("inspection error: %w", err) } if err = a.cache.PutBlob(cacheKey, blobInfo); err != nil { - return types.ArtifactReference{}, xerrors.Errorf("failed to store blob (%s) in cache: %w", cacheKey, err) + return artifact.Reference{}, xerrors.Errorf("failed to store blob (%s) in cache: %w", cacheKey, err) } - return types.ArtifactReference{ + return artifact.Reference{ Name: a.snapshotID, - Type: types.ArtifactVM, + Type: artifact.TypeVM, ID: cacheKey, // use a cache key as pseudo artifact ID BlobIDs: []string{cacheKey}, }, nil @@ -90,7 +90,7 @@ func (a *EBS) openEBS(ctx context.Context) (*io.SectionReader, error) { return r, nil } -func (a *EBS) Clean(_ types.ArtifactReference) error { +func (a *EBS) Clean(_ artifact.Reference) error { return nil } diff --git a/pkg/fanal/artifact/vm/file.go b/pkg/fanal/artifact/vm/file.go index 58fd4d46c96a..7968cf44681b 100644 --- a/pkg/fanal/artifact/vm/file.go +++ b/pkg/fanal/artifact/vm/file.go @@ -12,6 +12,7 @@ import ( "github.com/opencontainers/go-digest" "golang.org/x/xerrors" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/fanal/cache" "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/fanal/vm" @@ -68,24 +69,24 @@ func newFile(filePath string, storage Storage) (*ImageFile, error) { }, nil } -func (a *ImageFile) Inspect(ctx context.Context) (types.ArtifactReference, error) { +func (a *ImageFile) Inspect(ctx context.Context) (artifact.Reference, error) { blobInfo, err := a.Analyze(ctx, a.reader) if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("inspection error: %w", err) + return artifact.Reference{}, xerrors.Errorf("inspection error: %w", err) } cacheKey, err := a.calcCacheKey(blobInfo) if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("cache calculation error: %w", err) + return artifact.Reference{}, xerrors.Errorf("cache calculation error: %w", err) } if err = a.cache.PutBlob(cacheKey, blobInfo); err != nil { - return types.ArtifactReference{}, xerrors.Errorf("failed to store blob (%s) in cache: %w", cacheKey, err) + return artifact.Reference{}, xerrors.Errorf("failed to store blob (%s) in cache: %w", cacheKey, err) } - return types.ArtifactReference{ + return artifact.Reference{ Name: a.filePath, - Type: types.ArtifactVM, + Type: artifact.TypeVM, ID: cacheKey, // use a cache key as pseudo artifact ID BlobIDs: []string{cacheKey}, }, nil @@ -107,7 +108,7 @@ func (a *ImageFile) calcCacheKey(blobInfo types.BlobInfo) (string, error) { return cacheKey, nil } -func (a *ImageFile) Clean(reference types.ArtifactReference) error { +func (a *ImageFile) Clean(reference artifact.Reference) error { _ = a.file.Close() return a.cache.DeleteBlobs(reference.BlobIDs) } diff --git a/pkg/fanal/artifact/vm/vm_test.go b/pkg/fanal/artifact/vm/vm_test.go index b510662a2dbf..bbe04d6eba84 100644 --- a/pkg/fanal/artifact/vm/vm_test.go +++ b/pkg/fanal/artifact/vm/vm_test.go @@ -112,7 +112,7 @@ func TestArtifact_Inspect(t *testing.T) { missingBlobsExpectation cache.ArtifactCacheMissingBlobsExpectation putBlobExpectation cache.ArtifactCachePutBlobExpectation putArtifactExpectations []cache.ArtifactCachePutArtifactExpectation - want types.ArtifactReference + want artifact.Reference wantErr string }{ { @@ -136,9 +136,9 @@ func TestArtifact_Inspect(t *testing.T) { }, }, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "rawdata.img", - Type: types.ArtifactVM, + Type: artifact.TypeVM, ID: "sha256:84a726d23c36d0e1857101969b257c1199de5432489d44581750d54ea8eff8cd", BlobIDs: []string{ "sha256:84a726d23c36d0e1857101969b257c1199de5432489d44581750d54ea8eff8cd", @@ -172,9 +172,9 @@ func TestArtifact_Inspect(t *testing.T) { }, }, }, - want: types.ArtifactReference{ + want: artifact.Reference{ Name: "ebs-012345", - Type: types.ArtifactVM, + Type: artifact.TypeVM, ID: "sha256:c28da2df41e019b5d18459440178341ec05e9082b12b6f11afe73f0600bfe96a", BlobIDs: []string{ "sha256:c28da2df41e019b5d18459440178341ec05e9082b12b6f11afe73f0600bfe96a", diff --git a/pkg/fanal/test/integration/containerd_test.go b/pkg/fanal/test/integration/containerd_test.go index 9ca993ec0627..c335159fb851 100644 --- a/pkg/fanal/test/integration/containerd_test.go +++ b/pkg/fanal/test/integration/containerd_test.go @@ -295,13 +295,13 @@ func localImageTestWithNamespace(t *testing.T, namespace string) { name string imageName string tarArchive string - wantMetadata types.ImageMetadata + wantMetadata artifact.ImageMetadata }{ { name: "alpine 3.10", imageName: "ghcr.io/aquasecurity/trivy-test-images:alpine-310", tarArchive: "../../../../integration/testdata/fixtures/images/alpine-310.tar.gz", - wantMetadata: types.ImageMetadata{ + wantMetadata: artifact.ImageMetadata{ ID: "sha256:961769676411f082461f9ef46626dd7a2d1e2b2a38e6a44364bcbecf51e66dd4", DiffIDs: []string{ "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0", @@ -349,7 +349,7 @@ func localImageTestWithNamespace(t *testing.T, namespace string) { name: "vulnimage", imageName: "ghcr.io/aquasecurity/trivy-test-images:vulnimage", tarArchive: "../../../../integration/testdata/fixtures/images/vulnimage.tar.gz", - wantMetadata: types.ImageMetadata{ + wantMetadata: artifact.ImageMetadata{ ID: "sha256:c17083664da903e13e9092fa3a3a1aeee2431aa2728298e3dbcec72f26369c41", DiffIDs: []string{ "sha256:ebf12965380b39889c99a9c02e82ba465f887b45975b6e389d42e9e6a3857888", @@ -746,12 +746,12 @@ func TestContainerd_PullImage(t *testing.T) { tests := []struct { name string imageName string - wantMetadata types.ImageMetadata + wantMetadata artifact.ImageMetadata }{ { name: "remote alpine 3.10", imageName: "ghcr.io/aquasecurity/trivy-test-images:alpine-310", - wantMetadata: types.ImageMetadata{ + wantMetadata: artifact.ImageMetadata{ ID: "sha256:961769676411f082461f9ef46626dd7a2d1e2b2a38e6a44364bcbecf51e66dd4", DiffIDs: []string{ "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0", diff --git a/pkg/fanal/types/artifact.go b/pkg/fanal/types/artifact.go index ff8da07b4e2c..3b3d9b2472a0 100644 --- a/pkg/fanal/types/artifact.go +++ b/pkg/fanal/types/artifact.go @@ -1,17 +1,9 @@ package types import ( - "encoding/json" - "strings" "time" - v1 "github.com/google/go-containerregistry/pkg/v1" - "github.com/package-url/packageurl-go" "github.com/samber/lo" - "golang.org/x/xerrors" - - "github.com/aquasecurity/trivy/pkg/digest" - "github.com/aquasecurity/trivy/pkg/sbom/core" ) type OS struct { @@ -66,260 +58,6 @@ type Layer struct { CreatedBy string `json:",omitempty"` } -type Relationship int - -const ( - RelationshipUnknown Relationship = iota - RelationshipRoot - RelationshipDirect - RelationshipIndirect -) - -var relationshipNames = [...]string{ - "unknown", - "root", - "direct", - "indirect", -} - -func (r Relationship) String() string { - if r <= RelationshipUnknown || int(r) >= len(relationshipNames) { - return "unknown" - } - return relationshipNames[r] -} - -func (r Relationship) MarshalJSON() ([]byte, error) { - return json.Marshal(r.String()) -} - -func (r *Relationship) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - for i, name := range relationshipNames { - if s == name { - *r = Relationship(i) - return nil - } - } - return xerrors.Errorf("invalid relationship (%s)", s) -} - -type Package struct { - ID string `json:",omitempty"` - Name string `json:",omitempty"` - Identifier PkgIdentifier `json:",omitempty"` - Version string `json:",omitempty"` - Release string `json:",omitempty"` - Epoch int `json:",omitempty"` - Arch string `json:",omitempty"` - Dev bool `json:",omitempty"` - SrcName string `json:",omitempty"` - SrcVersion string `json:",omitempty"` - SrcRelease string `json:",omitempty"` - SrcEpoch int `json:",omitempty"` - Licenses []string `json:",omitempty"` - Maintainer string `json:",omitempty"` - ExternalReferences []ExternalRef `json:"-"` - - Modularitylabel string `json:",omitempty"` // only for Red Hat based distributions - BuildInfo *BuildInfo `json:",omitempty"` // only for Red Hat - - Indirect bool `json:",omitempty"` // Deprecated: Use relationship. Kept for backward compatibility. - Relationship Relationship `json:",omitempty"` - - // Dependencies of this package - // Note: it may have interdependencies, which may lead to infinite loops. - DependsOn []string `json:",omitempty"` - - Layer Layer `json:",omitempty"` - - // Each package metadata have the file path, while the package from lock files does not have. - FilePath string `json:",omitempty"` - - // This is required when using SPDX formats. Otherwise, it will be empty. - Digest digest.Digest `json:",omitempty"` - - // lines from the lock file where the dependency is written - Locations Locations `json:",omitempty"` - - // Files installed by the package - InstalledFiles []string `json:",omitempty"` -} - -// PkgIdentifier represents a software identifiers in one of more of the supported formats. -type PkgIdentifier struct { - UID string `json:",omitempty"` // Calculated by the package struct - PURL *packageurl.PackageURL `json:"-"` - BOMRef string `json:",omitempty"` // For CycloneDX -} - -// MarshalJSON customizes the JSON encoding of PkgIdentifier. -func (id *PkgIdentifier) MarshalJSON() ([]byte, error) { - var p string - if id.PURL != nil { - p = id.PURL.String() - } - - type Alias PkgIdentifier - return json.Marshal(&struct { - PURL string `json:",omitempty"` - *Alias - }{ - PURL: p, - Alias: (*Alias)(id), - }) -} - -// UnmarshalJSON customizes the JSON decoding of PkgIdentifier. -func (id *PkgIdentifier) UnmarshalJSON(data []byte) error { - type Alias PkgIdentifier - aux := &struct { - PURL string `json:",omitempty"` - *Alias - }{ - Alias: (*Alias)(id), - } - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - - if aux.PURL != "" { - p, err := packageurl.FromString(aux.PURL) - if err != nil { - return err - } else if len(p.Qualifiers) == 0 { - p.Qualifiers = nil - } - id.PURL = &p - } - - return nil -} - -func (id *PkgIdentifier) Empty() bool { - return id.UID == "" && id.PURL == nil && id.BOMRef == "" -} - -func (id *PkgIdentifier) Match(s string) bool { - // Encode string as PURL - if strings.HasPrefix(s, "pkg:") { - if p, err := packageurl.FromString(s); err == nil { - s = p.String() - } - } - - switch { - case id.BOMRef == s: - return true - case id.PURL != nil && id.PURL.String() == s: - return true - } - return false -} - -type Dependency struct { - ID string - DependsOn []string -} - -type Dependencies []Dependency - -func (deps Dependencies) Len() int { return len(deps) } -func (deps Dependencies) Less(i, j int) bool { - return deps[i].ID < deps[j].ID -} -func (deps Dependencies) Swap(i, j int) { deps[i], deps[j] = deps[j], deps[i] } - -type Location struct { - StartLine int `json:",omitempty"` - EndLine int `json:",omitempty"` -} - -type Locations []Location - -func (locs Locations) Len() int { return len(locs) } -func (locs Locations) Less(i, j int) bool { - return locs[i].StartLine < locs[j].StartLine -} -func (locs Locations) Swap(i, j int) { locs[i], locs[j] = locs[j], locs[i] } - -type ExternalRef struct { - Type RefType - URL string -} - -type RefType string - -const ( - RefVCS RefType = "vcs" - RefOther RefType = "other" -) - -// BuildInfo represents information under /root/buildinfo in RHEL -type BuildInfo struct { - ContentSets []string `json:",omitempty"` - Nvr string `json:",omitempty"` - Arch string `json:",omitempty"` -} - -func (pkg *Package) Empty() bool { - return pkg.Name == "" || pkg.Version == "" -} - -type Packages []Package - -func (pkgs Packages) Len() int { - return len(pkgs) -} - -func (pkgs Packages) Swap(i, j int) { - pkgs[i], pkgs[j] = pkgs[j], pkgs[i] -} - -func (pkgs Packages) Less(i, j int) bool { - switch { - case pkgs[i].Relationship != pkgs[j].Relationship: - if pkgs[i].Relationship == RelationshipUnknown { - return false - } else if pkgs[j].Relationship == RelationshipUnknown { - return true - } - return pkgs[i].Relationship < pkgs[j].Relationship - case pkgs[i].Name != pkgs[j].Name: - return pkgs[i].Name < pkgs[j].Name - case pkgs[i].Version != pkgs[j].Version: - return pkgs[i].Version < pkgs[j].Version - } - return pkgs[i].FilePath < pkgs[j].FilePath -} - -// ParentDeps returns a map where the keys are package IDs and the values are the packages -// that depend on the respective package ID (parent dependencies). -func (pkgs Packages) ParentDeps() map[string]Packages { - parents := make(map[string]Packages) - for _, pkg := range pkgs { - for _, dependOn := range pkg.DependsOn { - parents[dependOn] = append(parents[dependOn], pkg) - } - } - - for k, v := range parents { - parents[k] = lo.UniqBy(v, func(pkg Package) string { - return pkg.ID - }) - } - return parents -} - -type SrcPackage struct { - Name string `json:"name"` - Version string `json:"version"` - BinaryNames []string `json:"binaryNames"` -} - type PackageInfo struct { FilePath string Packages Packages @@ -342,39 +80,6 @@ type File struct { Content []byte } -// ArtifactType represents a type of artifact -type ArtifactType string - -const ( - ArtifactContainerImage ArtifactType = "container_image" - ArtifactFilesystem ArtifactType = "filesystem" - ArtifactRepository ArtifactType = "repository" - ArtifactCycloneDX ArtifactType = "cyclonedx" - ArtifactSPDX ArtifactType = "spdx" - ArtifactAWSAccount ArtifactType = "aws_account" - ArtifactVM ArtifactType = "vm" -) - -// ArtifactReference represents a reference of container image, local filesystem and repository -type ArtifactReference struct { - Name string // image name, tar file name, directory or repository name - Type ArtifactType - ID string - BlobIDs []string - ImageMetadata ImageMetadata - - // SBOM - BOM *core.BOM -} - -type ImageMetadata struct { - ID string // image ID - DiffIDs []string // uncompressed layer IDs - RepoTags []string - RepoDigests []string - ConfigFile v1.ConfigFile -} - // ArtifactInfo is stored in cache type ArtifactInfo struct { SchemaVersion int diff --git a/pkg/fanal/types/package.go b/pkg/fanal/types/package.go new file mode 100644 index 000000000000..0a281326b35d --- /dev/null +++ b/pkg/fanal/types/package.go @@ -0,0 +1,260 @@ +package types + +import ( + "encoding/json" + "strings" + + "github.com/package-url/packageurl-go" + "github.com/samber/lo" + "golang.org/x/xerrors" + + "github.com/aquasecurity/trivy/pkg/digest" +) + +type Relationship int + +const ( + RelationshipUnknown Relationship = iota + RelationshipRoot + RelationshipDirect + RelationshipIndirect +) + +var relationshipNames = [...]string{ + "unknown", + "root", + "direct", + "indirect", +} + +func (r Relationship) String() string { + if r <= RelationshipUnknown || int(r) >= len(relationshipNames) { + return "unknown" + } + return relationshipNames[r] +} + +func (r Relationship) MarshalJSON() ([]byte, error) { + return json.Marshal(r.String()) +} + +func (r *Relationship) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + for i, name := range relationshipNames { + if s == name { + *r = Relationship(i) + return nil + } + } + return xerrors.Errorf("invalid relationship (%s)", s) +} + +// PkgIdentifier represents a software identifiers in one of more of the supported formats. +type PkgIdentifier struct { + UID string `json:",omitempty"` // Calculated by the package struct + PURL *packageurl.PackageURL `json:"-"` + BOMRef string `json:",omitempty"` // For CycloneDX +} + +// MarshalJSON customizes the JSON encoding of PkgIdentifier. +func (id *PkgIdentifier) MarshalJSON() ([]byte, error) { + var p string + if id.PURL != nil { + p = id.PURL.String() + } + + type Alias PkgIdentifier + return json.Marshal(&struct { + PURL string `json:",omitempty"` + *Alias + }{ + PURL: p, + Alias: (*Alias)(id), + }) +} + +// UnmarshalJSON customizes the JSON decoding of PkgIdentifier. +func (id *PkgIdentifier) UnmarshalJSON(data []byte) error { + type Alias PkgIdentifier + aux := &struct { + PURL string `json:",omitempty"` + *Alias + }{ + Alias: (*Alias)(id), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + + if aux.PURL != "" { + p, err := packageurl.FromString(aux.PURL) + if err != nil { + return err + } else if len(p.Qualifiers) == 0 { + p.Qualifiers = nil + } + id.PURL = &p + } + + return nil +} + +func (id *PkgIdentifier) Empty() bool { + return id.UID == "" && id.PURL == nil && id.BOMRef == "" +} + +func (id *PkgIdentifier) Match(s string) bool { + // Encode string as PURL + if strings.HasPrefix(s, "pkg:") { + if p, err := packageurl.FromString(s); err == nil { + s = p.String() + } + } + + switch { + case id.BOMRef == s: + return true + case id.PURL != nil && id.PURL.String() == s: + return true + } + return false +} + +type Location struct { + StartLine int `json:",omitempty"` + EndLine int `json:",omitempty"` +} + +type Locations []Location + +func (locs Locations) Len() int { return len(locs) } +func (locs Locations) Less(i, j int) bool { + return locs[i].StartLine < locs[j].StartLine +} +func (locs Locations) Swap(i, j int) { locs[i], locs[j] = locs[j], locs[i] } + +type ExternalRef struct { + Type RefType + URL string +} + +type RefType string + +const ( + RefVCS RefType = "vcs" + RefOther RefType = "other" +) + +// BuildInfo represents information under /root/buildinfo in RHEL +type BuildInfo struct { + ContentSets []string `json:",omitempty"` + Nvr string `json:",omitempty"` + Arch string `json:",omitempty"` +} + +type Package struct { + ID string `json:",omitempty"` + Name string `json:",omitempty"` + Identifier PkgIdentifier `json:",omitempty"` + Version string `json:",omitempty"` + Release string `json:",omitempty"` + Epoch int `json:",omitempty"` + Arch string `json:",omitempty"` + Dev bool `json:",omitempty"` + SrcName string `json:",omitempty"` + SrcVersion string `json:",omitempty"` + SrcRelease string `json:",omitempty"` + SrcEpoch int `json:",omitempty"` + Licenses []string `json:",omitempty"` + Maintainer string `json:",omitempty"` + ExternalReferences []ExternalRef `json:"-"` + + Modularitylabel string `json:",omitempty"` // only for Red Hat based distributions + BuildInfo *BuildInfo `json:",omitempty"` // only for Red Hat + + Indirect bool `json:",omitempty"` // Deprecated: Use relationship. Kept for backward compatibility. + Relationship Relationship `json:",omitempty"` + + // Dependencies of this package + // Note: it may have interdependencies, which may lead to infinite loops. + DependsOn []string `json:",omitempty"` + + Layer Layer `json:",omitempty"` + + // Each package metadata have the file path, while the package from lock files does not have. + FilePath string `json:",omitempty"` + + // This is required when using SPDX formats. Otherwise, it will be empty. + Digest digest.Digest `json:",omitempty"` + + // lines from the lock file where the dependency is written + Locations Locations `json:",omitempty"` + + // Files installed by the package + InstalledFiles []string `json:",omitempty"` +} + +func (pkg *Package) Empty() bool { + return pkg.Name == "" || pkg.Version == "" +} + +type Packages []Package + +func (pkgs Packages) Len() int { + return len(pkgs) +} + +func (pkgs Packages) Swap(i, j int) { + pkgs[i], pkgs[j] = pkgs[j], pkgs[i] +} + +func (pkgs Packages) Less(i, j int) bool { + switch { + case pkgs[i].Relationship != pkgs[j].Relationship: + if pkgs[i].Relationship == RelationshipUnknown { + return false + } else if pkgs[j].Relationship == RelationshipUnknown { + return true + } + return pkgs[i].Relationship < pkgs[j].Relationship + case pkgs[i].Name != pkgs[j].Name: + return pkgs[i].Name < pkgs[j].Name + case pkgs[i].Version != pkgs[j].Version: + return pkgs[i].Version < pkgs[j].Version + } + return pkgs[i].FilePath < pkgs[j].FilePath +} + +// ParentDeps returns a map where the keys are package IDs and the values are the packages +// that depend on the respective package ID (parent dependencies). +func (pkgs Packages) ParentDeps() map[string]Packages { + parents := make(map[string]Packages) + for _, pkg := range pkgs { + for _, dependOn := range pkg.DependsOn { + parents[dependOn] = append(parents[dependOn], pkg) + } + } + + for k, v := range parents { + parents[k] = lo.UniqBy(v, func(pkg Package) string { + return pkg.ID + }) + } + return parents +} + +type Dependency struct { + ID string + DependsOn []string +} + +type Dependencies []Dependency + +func (deps Dependencies) Len() int { return len(deps) } +func (deps Dependencies) Less(i, j int) bool { + return deps[i].ID < deps[j].ID +} +func (deps Dependencies) Swap(i, j int) { deps[i], deps[j] = deps[j], deps[i] } diff --git a/pkg/k8s/scanner/scanner.go b/pkg/k8s/scanner/scanner.go index 2ac380dadb58..95761ad445a8 100644 --- a/pkg/k8s/scanner/scanner.go +++ b/pkg/k8s/scanner/scanner.go @@ -379,7 +379,7 @@ func (s *Scanner) clusterInfoToReportResources(allArtifact []*artifacts.Artifact Version: comp.Version, Type: core.TypeApplication, Properties: toProperties(comp.Properties, k8sCoreComponentNamespace), - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: generatePURL(comp.Name, comp.Version, nodeName), }, } @@ -406,7 +406,7 @@ func (s *Scanner) clusterInfoToReportResources(allArtifact []*artifacts.Artifact Type: core.TypeContainerImage, Name: name, Version: cDigest, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: imagePURL.Unwrap(), }, Properties: []core.Property{ @@ -439,7 +439,7 @@ func (s *Scanner) clusterInfoToReportResources(allArtifact []*artifacts.Artifact Name: cf.Name, Version: cf.Version, Properties: toProperties(cf.Properties, k8sCoreComponentNamespace), - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: generatePURL(cf.Name, cf.Version, nodeName), }, Root: true, @@ -512,7 +512,7 @@ func (s *Scanner) nodeComponent(b *core.BOM, nf bom.NodeInfo) *core.Component { Namespace: k8sCoreComponentNamespace, }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: generatePURL(kubelet, kubeletVersion, nf.NodeName), }, } @@ -534,7 +534,7 @@ func (s *Scanner) nodeComponent(b *core.BOM, nf bom.NodeInfo) *core.Component { Namespace: k8sCoreComponentNamespace, }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: packageurl.NewPackageURL(packageurl.TypeGolang, "", runtimeName, runtimeVersion, packageurl.Qualifiers{}, ""), }, } diff --git a/pkg/k8s/scanner/scanner_test.go b/pkg/k8s/scanner/scanner_test.go index 9269f78cf11b..69429a6f4d48 100644 --- a/pkg/k8s/scanner/scanner_test.go +++ b/pkg/k8s/scanner/scanner_test.go @@ -2,6 +2,7 @@ package scanner import ( "context" + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/sbom/core" "github.com/aquasecurity/trivy/pkg/uuid" "github.com/stretchr/testify/require" @@ -99,7 +100,7 @@ func TestScanner_Scan(t *testing.T) { Namespace: k8sCoreComponentNamespace, }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: "golang", Name: "github.com/containerd/containerd", @@ -113,7 +114,7 @@ func TestScanner_Scan(t *testing.T) { Type: core.TypeApplication, Name: "k8s.io/apiserver", Version: "1.21.1", - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: purl.TypeK8s, Name: "k8s.io/apiserver", @@ -138,7 +139,7 @@ func TestScanner_Scan(t *testing.T) { Namespace: k8sCoreComponentNamespace, }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: "k8s", Name: "k8s.io/kubelet", @@ -150,7 +151,7 @@ func TestScanner_Scan(t *testing.T) { { Type: core.TypeApplication, Name: "node-core-components", - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "3ff14136-e09f-4df9-80ea-000000000006", }, }, @@ -158,7 +159,7 @@ func TestScanner_Scan(t *testing.T) { Type: core.TypeContainerImage, Name: "k8s.gcr.io/kube-apiserver", Version: "sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f", - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: "oci", Name: "kube-apiserver", @@ -199,7 +200,7 @@ func TestScanner_Scan(t *testing.T) { Namespace: "", }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "3ff14136-e09f-4df9-80ea-000000000005", }, }, @@ -220,7 +221,7 @@ func TestScanner_Scan(t *testing.T) { Namespace: k8sCoreComponentNamespace, }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: purl.TypeK8s, Name: "k8s.io/kubernetes", @@ -264,7 +265,7 @@ func TestScanner_Scan(t *testing.T) { Namespace: k8sCoreComponentNamespace, }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "3ff14136-e09f-4df9-80ea-000000000004", }, }, diff --git a/pkg/report/github/github.go b/pkg/report/github/github.go index 8a1ef95c74e1..6441d96630e4 100644 --- a/pkg/report/github/github.go +++ b/pkg/report/github/github.go @@ -12,6 +12,7 @@ import ( "golang.org/x/xerrors" "github.com/aquasecurity/trivy/pkg/clock" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/purl" "github.com/aquasecurity/trivy/pkg/types" @@ -105,7 +106,7 @@ 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 { - if report.ArtifactType == ftypes.ArtifactContainerImage { + if report.ArtifactType == artifact.TypeContainerImage { // `RepoDigests` ~= /@sha256: // `RepoTag` ~= /: // By concatenating the hash from `RepoDigests` at the end of `RepoTag` we get all the information diff --git a/pkg/report/predicate/vuln_test.go b/pkg/report/predicate/vuln_test.go index 8477a3971bd4..0473441e30c4 100644 --- a/pkg/report/predicate/vuln_test.go +++ b/pkg/report/predicate/vuln_test.go @@ -12,7 +12,7 @@ import ( dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" "github.com/aquasecurity/trivy/pkg/clock" - ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/report/predicate" "github.com/aquasecurity/trivy/pkg/types" ) @@ -49,7 +49,7 @@ func TestWriter_Write(t *testing.T) { Result: types.Report{ SchemaVersion: 2, ArtifactName: "alpine:3.14", - ArtifactType: ftypes.ArtifactType(""), + ArtifactType: artifact.Type(""), Metadata: types.Metadata{}, Results: types.Results{ { diff --git a/pkg/report/sarif.go b/pkg/report/sarif.go index 2f9dd5891516..ae84b8ff987f 100644 --- a/pkg/report/sarif.go +++ b/pkg/report/sarif.go @@ -13,6 +13,7 @@ import ( "github.com/owenrumney/go-sarif/v2/sarif" "golang.org/x/xerrors" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" ) @@ -131,7 +132,7 @@ func (sw *SarifWriter) Write(ctx context.Context, report types.Report) error { sw.run.Tool.Driver.WithVersion(sw.Version) sw.run.Tool.Driver.WithFullName("Trivy Vulnerability Scanner") sw.locationCache = make(map[string][]location) - if report.ArtifactType == ftypes.ArtifactContainerImage { + if report.ArtifactType == artifact.TypeContainerImage { sw.run.Properties = sarif.Properties{ "imageName": report.ArtifactName, "repoTags": report.Metadata.RepoTags, diff --git a/pkg/report/sarif_test.go b/pkg/report/sarif_test.go index fe46514002b6..31a5f0d8a620 100644 --- a/pkg/report/sarif_test.go +++ b/pkg/report/sarif_test.go @@ -12,6 +12,7 @@ import ( dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/report" "github.com/aquasecurity/trivy/pkg/types" @@ -27,7 +28,7 @@ func TestReportWriter_Sarif(t *testing.T) { name: "report with vulnerabilities", input: types.Report{ ArtifactName: "debian:9", - ArtifactType: ftypes.ArtifactContainerImage, + ArtifactType: artifact.TypeContainerImage, Metadata: types.Metadata{ RepoTags: []string{ "debian:9", diff --git a/pkg/report/writer.go b/pkg/report/writer.go index d732ec397a1f..b4966d88a700 100644 --- a/pkg/report/writer.go +++ b/pkg/report/writer.go @@ -9,7 +9,7 @@ import ( "golang.org/x/xerrors" cr "github.com/aquasecurity/trivy/pkg/compliance/report" - ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/flag" "github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/report/cyclonedx" @@ -82,7 +82,7 @@ func Write(ctx context.Context, report types.Report, option flag.Options) (err e } case types.FormatSarif: target := "" - if report.ArtifactType == ftypes.ArtifactFilesystem { + if report.ArtifactType == artifact.TypeFilesystem { target = option.Target } writer = &SarifWriter{ diff --git a/pkg/sbom/core/bom.go b/pkg/sbom/core/bom.go index 893796a0fe0d..68ba8dab76d5 100644 --- a/pkg/sbom/core/bom.go +++ b/pkg/sbom/core/bom.go @@ -3,10 +3,9 @@ package core import ( "sort" - "github.com/package-url/packageurl-go" - dtypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy/pkg/digest" + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/uuid" ) @@ -124,14 +123,14 @@ type Component struct { // SPDX: package.licenseConcluded, package.licenseDeclared Licenses []string - // PkgID has PURL and BOMRef for the component + // PkgIdentifier has PURL and BOMRef for the component // PURL: // CycloneDX: component.purl // SPDX: package.externalRefs.referenceLocator // BOMRef: // CycloneDX: component.bom-ref // SPDX: N/A - PkgID PkgID + PkgIdentifier ftypes.PkgIdentifier // Supplier is the name of the supplier of the component // CycloneDX: component.supplier @@ -188,11 +187,6 @@ type Relationship struct { Type RelationshipType } -type PkgID struct { - PURL *packageurl.PackageURL - BOMRef string -} - type Vulnerability struct { dtypes.Vulnerability ID string @@ -222,8 +216,8 @@ func (b *BOM) setupComponent(c *Component) { if c.id == uuid.Nil { c.id = uuid.New() } - if c.PkgID.PURL != nil { - p := c.PkgID.PURL.String() + if c.PkgIdentifier.PURL != nil { + p := c.PkgIdentifier.PURL.String() b.purls[p] = append(b.purls[p], c.id) } sort.Sort(c.Properties) @@ -281,7 +275,7 @@ func (b *BOM) Root() *Component { return nil } if b.opts.GenerateBOMRef { - root.PkgID.BOMRef = b.bomRef(root) + root.PkgIdentifier.BOMRef = b.bomRef(root) } return root } @@ -290,7 +284,7 @@ func (b *BOM) Components() map[uuid.UUID]*Component { // Fill in BOMRefs for components if b.opts.GenerateBOMRef { for id, c := range b.components { - b.components[id].PkgID.BOMRef = b.bomRef(c) + b.components[id].PkgIdentifier.BOMRef = b.bomRef(c) } } return b.components @@ -312,14 +306,14 @@ func (b *BOM) NumComponents() int { // When multiple lock files have the same dependency with the same name and version, PURL in the BOM can conflict. // In that case, PURL cannot be used as a unique identifier, and UUIDv4 be used for BOMRef. func (b *BOM) bomRef(c *Component) string { - if c.PkgID.BOMRef != "" { - return c.PkgID.BOMRef + if c.PkgIdentifier.BOMRef != "" { + return c.PkgIdentifier.BOMRef } // Return the UUID of the component if the PURL is not present. - if c.PkgID.PURL == nil { + if c.PkgIdentifier.PURL == nil { return c.id.String() } - p := c.PkgID.PURL.String() + p := c.PkgIdentifier.PURL.String() // Return the UUID of the component if the PURL is not unique in the BOM. if len(b.purls[p]) > 1 { diff --git a/pkg/sbom/cyclonedx/marshal.go b/pkg/sbom/cyclonedx/marshal.go index a8d96e4b12e3..5b7241254d25 100644 --- a/pkg/sbom/cyclonedx/marshal.go +++ b/pkg/sbom/cyclonedx/marshal.go @@ -108,12 +108,12 @@ func (m *Marshaler) MarshalComponent(component *core.Component) (*cdx.Component, } cdxComponent := &cdx.Component{ - BOMRef: component.PkgID.BOMRef, + BOMRef: component.PkgIdentifier.BOMRef, Type: componentType, Name: component.Name, Group: component.Group, Version: component.Version, - PackageURL: m.PackageURL(component.PkgID.PURL), + PackageURL: m.PackageURL(component.PkgIdentifier.PURL), Supplier: m.Supplier(component.Supplier), Hashes: m.Hashes(component.Files), Licenses: m.Licenses(component.Licenses), diff --git a/pkg/sbom/cyclonedx/marshal_test.go b/pkg/sbom/cyclonedx/marshal_test.go index d71c3c9ed074..d3d104b28347 100644 --- a/pkg/sbom/cyclonedx/marshal_test.go +++ b/pkg/sbom/cyclonedx/marshal_test.go @@ -2,6 +2,7 @@ package cyclonedx_test import ( "context" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/sbom/core" "github.com/package-url/packageurl-go" "testing" @@ -29,7 +30,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { Root: true, Type: core.TypeApplication, Name: "jackson-databind-2.13.4.1.jar", - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "aff65b54-6009-4c32-968d-748949ef46e8", }, Properties: []core.Property{ @@ -50,7 +51,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "rails:latest", - ArtifactType: ftypes.ArtifactContainerImage, + ArtifactType: artifact.TypeContainerImage, Metadata: types.Metadata{ Size: 1024, OS: &ftypes.OS{ @@ -668,7 +669,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "centos:latest", - ArtifactType: ftypes.ArtifactContainerImage, + ArtifactType: artifact.TypeContainerImage, Metadata: types.Metadata{ Size: 1024, OS: &ftypes.OS{ @@ -1229,7 +1230,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "masahiro331/CVE-2021-41098", - ArtifactType: ftypes.ArtifactFilesystem, + ArtifactType: artifact.TypeFilesystem, Results: types.Results{ { Target: "Gemfile.lock", @@ -1445,7 +1446,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "./report.cdx.json", - ArtifactType: ftypes.ArtifactCycloneDX, + ArtifactType: artifact.TypeCycloneDX, Results: types.Results{ { Target: "Java", @@ -1629,7 +1630,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "CVE-2023-34468", - ArtifactType: ftypes.ArtifactFilesystem, + ArtifactType: artifact.TypeFilesystem, Results: types.Results{ { Target: "Java", @@ -1926,7 +1927,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "test-aggregate", - ArtifactType: ftypes.ArtifactRepository, + ArtifactType: artifact.TypeRepository, Results: types.Results{ { Target: "Node.js", @@ -2039,7 +2040,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "empty/path", - ArtifactType: ftypes.ArtifactFilesystem, + ArtifactType: artifact.TypeFilesystem, Results: types.Results{}, }, want: &cdx.BOM{ diff --git a/pkg/sbom/cyclonedx/unmarshal.go b/pkg/sbom/cyclonedx/unmarshal.go index 9450a78a455c..71a0ee27b640 100644 --- a/pkg/sbom/cyclonedx/unmarshal.go +++ b/pkg/sbom/cyclonedx/unmarshal.go @@ -12,6 +12,7 @@ import ( "golang.org/x/xerrors" "github.com/aquasecurity/trivy/pkg/digest" + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/sbom/core" ) @@ -69,7 +70,7 @@ func (b *BOM) parseBOM(bom *cdx.BOM) error { if err != nil { return xerrors.Errorf("failed to parse root component: %w", err) } else if mComponent != nil { - components[mComponent.PkgID.BOMRef] = mComponent + components[mComponent.PkgIdentifier.BOMRef] = mComponent } // Parse dependencies and build relationships @@ -147,7 +148,7 @@ func (b *BOM) parseComponent(c cdx.Component) (*core.Component, error) { Digests: b.unmarshalHashes(c.Hashes), }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &purl, BOMRef: c.BOMRef, }, diff --git a/pkg/sbom/io/decode.go b/pkg/sbom/io/decode.go index 84039973c213..e4df3bee8489 100644 --- a/pkg/sbom/io/decode.go +++ b/pkg/sbom/io/decode.go @@ -135,7 +135,7 @@ func (m *Decoder) decodeComponents(sbom *types.SBOM) error { } // Third-party SBOMs may contain packages in types other than "Library" - if c.Type == core.TypeLibrary || c.PkgID.PURL != nil { + if c.Type == core.TypeLibrary || c.PkgIdentifier.PURL != nil { pkg, err := m.decodeLibrary(c) if errors.Is(err, ErrUnsupportedType) || errors.Is(err, ErrPURLEmpty) { continue @@ -184,7 +184,7 @@ func (m *Decoder) decodeApplication(c *core.Component) *ftypes.Application { } func (m *Decoder) decodeLibrary(c *core.Component) (*ftypes.Package, error) { - p := (*purl.PackageURL)(c.PkgID.PURL) + p := (*purl.PackageURL)(c.PkgIdentifier.PURL) if p == nil { log.Debug("Skipping a component without PURL", log.String("name", c.Name), log.String("version", c.Version)) @@ -226,7 +226,7 @@ func (m *Decoder) decodeLibrary(c *core.Component) (*ftypes.Package, error) { } } - pkg.Identifier.BOMRef = c.PkgID.BOMRef + pkg.Identifier.BOMRef = c.PkgIdentifier.BOMRef pkg.Licenses = c.Licenses for _, f := range c.Files { @@ -249,10 +249,10 @@ func (m *Decoder) decodeLibrary(c *core.Component) (*ftypes.Package, error) { // pkgName returns the package name. // PURL loses case-sensitivity (e.g. Go, Npm, PyPI), so we have to use an original package name. func (m *Decoder) pkgName(pkg *ftypes.Package, c *core.Component) string { - p := c.PkgID.PURL + p := c.PkgIdentifier.PURL // A name from PURL takes precedence for CocoaPods since it has subpath. - if c.PkgID.PURL.Type == packageurl.TypeCocoapods { + if c.PkgIdentifier.PURL.Type == packageurl.TypeCocoapods { return pkg.Name } diff --git a/pkg/sbom/io/encode.go b/pkg/sbom/io/encode.go index b6d1301d6f6e..4b715b023a08 100644 --- a/pkg/sbom/io/encode.go +++ b/pkg/sbom/io/encode.go @@ -10,6 +10,7 @@ import ( "golang.org/x/xerrors" "github.com/aquasecurity/trivy/pkg/digest" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/purl" "github.com/aquasecurity/trivy/pkg/sbom/core" @@ -61,7 +62,7 @@ func (e *Encoder) rootComponent(r types.Report) (*core.Component, error) { } switch r.ArtifactType { - case ftypes.ArtifactContainerImage: + case artifact.TypeContainerImage: root.Type = core.TypeContainerImage props = append(props, core.Property{ Name: core.PropertyImageID, @@ -73,16 +74,16 @@ func (e *Encoder) rootComponent(r types.Report) (*core.Component, error) { return nil, xerrors.Errorf("failed to new package url for oci: %w", err) } if p != nil { - root.PkgID.PURL = p.Unwrap() + root.PkgIdentifier.PURL = p.Unwrap() } - case ftypes.ArtifactVM: + case artifact.TypeVM: root.Type = core.TypeVM - case ftypes.ArtifactFilesystem: + case artifact.TypeFilesystem: root.Type = core.TypeFilesystem - case ftypes.ArtifactRepository: + case artifact.TypeRepository: root.Type = core.TypeRepository - case ftypes.ArtifactCycloneDX: + case artifact.TypeCycloneDX: return r.BOM.Root(), nil } @@ -346,7 +347,7 @@ func (*Encoder) component(result types.Result, pkg ftypes.Package) *core.Compone SrcName: pkg.SrcName, SrcVersion: utils.FormatSrcVersion(pkg), SrcFile: srcFile, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: pkg.Identifier.PURL, }, Supplier: pkg.Maintainer, diff --git a/pkg/sbom/io/encode_test.go b/pkg/sbom/io/encode_test.go index d45f70112592..e26dd83848e8 100644 --- a/pkg/sbom/io/encode_test.go +++ b/pkg/sbom/io/encode_test.go @@ -2,6 +2,7 @@ package io_test import ( dtypes "github.com/aquasecurity/trivy-db/pkg/types" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/sbom/core" sbomio "github.com/aquasecurity/trivy/pkg/sbom/io" @@ -27,7 +28,7 @@ func TestEncoder_Encode(t *testing.T) { report: types.Report{ SchemaVersion: 2, ArtifactName: "debian:12", - ArtifactType: ftypes.ArtifactContainerImage, + ArtifactType: artifact.TypeContainerImage, Metadata: types.Metadata{ OS: &ftypes.OS{ Family: ftypes.Debian, @@ -116,7 +117,7 @@ func TestEncoder_Encode(t *testing.T) { Type: core.TypeContainerImage, Name: "debian:12", Root: true, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: packageurl.TypeOCI, Name: "debian", @@ -163,7 +164,7 @@ func TestEncoder_Encode(t *testing.T) { Value: "debian", }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "3ff14136-e09f-4df9-80ea-000000000002", }, }, @@ -181,7 +182,7 @@ func TestEncoder_Encode(t *testing.T) { Value: "debian", }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: packageurl.TypeDebian, Name: "libc6", @@ -204,7 +205,7 @@ func TestEncoder_Encode(t *testing.T) { Value: "debian", }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: packageurl.TypeDebian, Name: "curl", @@ -237,7 +238,7 @@ func TestEncoder_Encode(t *testing.T) { Value: "jar", }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.apache.xmlgraphics", @@ -298,7 +299,7 @@ func TestEncoder_Encode(t *testing.T) { report: types.Report{ SchemaVersion: 2, ArtifactName: "gobinary", - ArtifactType: ftypes.ArtifactFilesystem, + ArtifactType: artifact.TypeFilesystem, Results: []types.Result{ { Target: "test", @@ -379,7 +380,7 @@ func TestEncoder_Encode(t *testing.T) { Value: "2", }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "3ff14136-e09f-4df9-80ea-000000000001", }, }, @@ -396,7 +397,7 @@ func TestEncoder_Encode(t *testing.T) { Value: "gobinary", }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "3ff14136-e09f-4df9-80ea-000000000002", }, }, @@ -414,7 +415,7 @@ func TestEncoder_Encode(t *testing.T) { Value: "gobinary", }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Namespace: "github.com/org", @@ -438,7 +439,7 @@ func TestEncoder_Encode(t *testing.T) { Value: "gobinary", }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Namespace: "github.com/org", @@ -463,7 +464,7 @@ func TestEncoder_Encode(t *testing.T) { Value: "gobinary", }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Namespace: "github.com/org", @@ -488,7 +489,7 @@ func TestEncoder_Encode(t *testing.T) { Value: "gobinary", }, }, - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Name: "stdlib", @@ -537,7 +538,7 @@ func TestEncoder_Encode(t *testing.T) { report: types.Report{ SchemaVersion: 2, ArtifactName: "debian:12", - ArtifactType: ftypes.ArtifactContainerImage, + ArtifactType: artifact.TypeContainerImage, Metadata: types.Metadata{ OS: &ftypes.OS{ Family: ftypes.Debian, diff --git a/pkg/sbom/spdx/marshal.go b/pkg/sbom/spdx/marshal.go index 3f72c6d69a20..2b29c7483024 100644 --- a/pkg/sbom/spdx/marshal.go +++ b/pkg/sbom/spdx/marshal.go @@ -229,8 +229,8 @@ func (m *Marshaler) packageDownloadLocation(root *core.Component) string { func (m *Marshaler) rootSPDXPackage(root *core.Component, pkgDownloadLocation string) (*spdx.Package, error) { var externalReferences []*spdx.PackageExternalReference // When the target is a container image, add PURL to the external references of the root package. - if root.PkgID.PURL != nil { - externalReferences = append(externalReferences, m.purlExternalReference(root.PkgID.PURL.String())) + if root.PkgIdentifier.PURL != nil { + externalReferences = append(externalReferences, m.purlExternalReference(root.PkgIdentifier.PURL.String())) } pkgID, err := calcPkgID(m.hasher, fmt.Sprintf("%s-%s", root.Name, root.Type)) @@ -304,8 +304,8 @@ func (m *Marshaler) spdxPackage(c *core.Component, pkgDownloadLocation string) ( } var pkgExtRefs []*spdx.PackageExternalReference - if c.PkgID.PURL != nil { - pkgExtRefs = []*spdx.PackageExternalReference{m.purlExternalReference(c.PkgID.PURL.String())} + if c.PkgIdentifier.PURL != nil { + pkgExtRefs = []*spdx.PackageExternalReference{m.purlExternalReference(c.PkgIdentifier.PURL.String())} } var digests []digest.Digest @@ -338,7 +338,7 @@ func (m *Marshaler) spdxPackage(c *core.Component, pkgDownloadLocation string) ( } func spdxPkgName(component *core.Component) string { - if p := component.PkgID.PURL; p != nil && component.Group != "" { + if p := component.PkgIdentifier.PURL; p != nil && component.Group != "" { if p.Type == packageurl.TypeMaven || p.Type == packageurl.TypeGradle { return component.Group + ":" + component.Name } diff --git a/pkg/sbom/spdx/marshal_test.go b/pkg/sbom/spdx/marshal_test.go index c4f2f7694d62..ee4c10949148 100644 --- a/pkg/sbom/spdx/marshal_test.go +++ b/pkg/sbom/spdx/marshal_test.go @@ -2,6 +2,7 @@ package spdx_test import ( "context" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/sbom/core" "github.com/package-url/packageurl-go" "hash/fnv" @@ -34,7 +35,7 @@ func TestMarshaler_Marshal(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "rails:latest", - ArtifactType: ftypes.ArtifactContainerImage, + ArtifactType: artifact.TypeContainerImage, Metadata: types.Metadata{ Size: 1024, OS: &ftypes.OS{ @@ -358,7 +359,7 @@ func TestMarshaler_Marshal(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "centos:latest", - ArtifactType: ftypes.ArtifactContainerImage, + ArtifactType: artifact.TypeContainerImage, Metadata: types.Metadata{ Size: 1024, OS: &ftypes.OS{ @@ -649,7 +650,7 @@ func TestMarshaler_Marshal(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "masahiro331/CVE-2021-41098", - ArtifactType: ftypes.ArtifactFilesystem, + ArtifactType: artifact.TypeFilesystem, Results: types.Results{ { Target: "Gemfile.lock", @@ -818,7 +819,7 @@ func TestMarshaler_Marshal(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "http://test-aggregate", - ArtifactType: ftypes.ArtifactRepository, + ArtifactType: artifact.TypeRepository, Results: types.Results{ { Target: "Node.js", @@ -937,7 +938,7 @@ func TestMarshaler_Marshal(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "empty/path", - ArtifactType: ftypes.ArtifactFilesystem, + ArtifactType: artifact.TypeFilesystem, Results: types.Results{}, }, wantSBOM: &spdx.Document{ @@ -985,7 +986,7 @@ func TestMarshaler_Marshal(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "secret", - ArtifactType: ftypes.ArtifactFilesystem, + ArtifactType: artifact.TypeFilesystem, Results: types.Results{ { Target: "key.pem", @@ -1047,7 +1048,7 @@ func TestMarshaler_Marshal(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "go-artifact", - ArtifactType: ftypes.ArtifactFilesystem, + ArtifactType: artifact.TypeFilesystem, Results: types.Results{ { Target: "/usr/local/bin/test", diff --git a/pkg/sbom/spdx/unmarshal.go b/pkg/sbom/spdx/unmarshal.go index bda18c16980a..719cdad15c3d 100644 --- a/pkg/sbom/spdx/unmarshal.go +++ b/pkg/sbom/spdx/unmarshal.go @@ -167,7 +167,7 @@ func (s *SPDX) parsePackage(spdxPkg spdx.Package) (*core.Component, error) { } // PURL - if component.PkgID.PURL, err = s.parseExternalReferences(spdxPkg.PackageExternalReferences); err != nil { + if component.PkgIdentifier.PURL, err = s.parseExternalReferences(spdxPkg.PackageExternalReferences); err != nil { return nil, xerrors.Errorf("external references error: %w", err) } diff --git a/pkg/scanner/scan.go b/pkg/scanner/scan.go index c5451167c709..7094e38c71fe 100644 --- a/pkg/scanner/scan.go +++ b/pkg/scanner/scan.go @@ -169,7 +169,7 @@ func (s Scanner) ScanArtifact(ctx context.Context, options types.ScanOptions) (t } // Layer makes sense only when scanning container images - if artifactInfo.Type != ftypes.ArtifactContainerImage { + if artifactInfo.Type != artifact.TypeContainerImage { removeLayer(results) } diff --git a/pkg/scanner/scan_test.go b/pkg/scanner/scan_test.go index 78606299303b..bc6a0d6696e2 100644 --- a/pkg/scanner/scan_test.go +++ b/pkg/scanner/scan_test.go @@ -37,12 +37,12 @@ func TestScanner_ScanArtifact(t *testing.T) { CtxAnything: true, }, Returns: artifact.ArtifactInspectReturns{ - Reference: ftypes.ArtifactReference{ + Reference: artifact.Reference{ Name: "alpine:3.11", - Type: ftypes.ArtifactContainerImage, + Type: artifact.TypeContainerImage, ID: "sha256:e7d92cdc71feacf90708cb59182d0df1b911f8ae022d29e8e95d75ca6a99776a", BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"}, - ImageMetadata: ftypes.ImageMetadata{ + ImageMetadata: artifact.ImageMetadata{ ID: "sha256:e389ae58922402a7ded319e79f06ac428d05698d8e61ecbe88d2cf850e42651d", DiffIDs: []string{"sha256:9a5d14f9f5503e55088666beef7e85a8d9625d4fa7418e2fe269e9c54bcb853c"}, RepoTags: []string{"alpine:3.11"}, @@ -100,7 +100,7 @@ func TestScanner_ScanArtifact(t *testing.T) { SchemaVersion: 2, CreatedAt: time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC), ArtifactName: "alpine:3.11", - ArtifactType: ftypes.ArtifactContainerImage, + ArtifactType: artifact.TypeContainerImage, Metadata: types.Metadata{ OS: &ftypes.OS{ Family: "alpine", @@ -168,7 +168,7 @@ func TestScanner_ScanArtifact(t *testing.T) { CtxAnything: true, }, Returns: artifact.ArtifactInspectReturns{ - Reference: ftypes.ArtifactReference{ + Reference: artifact.Reference{ Name: "alpine:3.11", ID: "sha256:e7d92cdc71feacf90708cb59182d0df1b911f8ae022d29e8e95d75ca6a99776a", BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"}, diff --git a/pkg/types/report.go b/pkg/types/report.go index e6c96d9564eb..baaeaab0a0c3 100644 --- a/pkg/types/report.go +++ b/pkg/types/report.go @@ -5,18 +5,19 @@ import ( v1 "github.com/google/go-containerregistry/pkg/v1" // nolint: goimports + "github.com/aquasecurity/trivy/pkg/fanal/artifact" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/sbom/core" ) // Report represents a scan result type Report struct { - SchemaVersion int `json:",omitempty"` - CreatedAt time.Time `json:",omitempty"` - ArtifactName string `json:",omitempty"` - ArtifactType ftypes.ArtifactType `json:",omitempty"` - Metadata Metadata `json:",omitempty"` - Results Results `json:",omitempty"` + SchemaVersion int `json:",omitempty"` + CreatedAt time.Time `json:",omitempty"` + ArtifactName string `json:",omitempty"` + ArtifactType artifact.Type `json:",omitempty"` + Metadata Metadata `json:",omitempty"` + Results Results `json:",omitempty"` // parsed SBOM BOM *core.BOM `json:"-"` // Just for internal usage, not exported in JSON diff --git a/pkg/vex/openvex.go b/pkg/vex/openvex.go index a6cae6de7ac8..ce049777e8cc 100644 --- a/pkg/vex/openvex.go +++ b/pkg/vex/openvex.go @@ -44,8 +44,8 @@ func (v *OpenVEX) Filter(result *types.Result, bom *core.BOM) { func (v *OpenVEX) Matches(vuln types.DetectedVulnerability, bom *core.BOM) []openvex.Statement { root := bom.Root() - if root != nil && root.PkgID.PURL != nil { - stmts := v.vex.Matches(vuln.VulnerabilityID, root.PkgID.PURL.String(), []string{vuln.PkgIdentifier.PURL.String()}) + if root != nil && root.PkgIdentifier.PURL != nil { + stmts := v.vex.Matches(vuln.VulnerabilityID, root.PkgIdentifier.PURL.String(), []string{vuln.PkgIdentifier.PURL.String()}) if len(stmts) != 0 { return stmts } diff --git a/pkg/vex/vex.go b/pkg/vex/vex.go index 0e47bf03bf52..64aa651d640c 100644 --- a/pkg/vex/vex.go +++ b/pkg/vex/vex.go @@ -11,7 +11,7 @@ import ( "github.com/sirupsen/logrus" "golang.org/x/xerrors" - ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/sbom" "github.com/aquasecurity/trivy/pkg/sbom/core" "github.com/aquasecurity/trivy/pkg/sbom/cyclonedx" @@ -68,7 +68,7 @@ func decodeCycloneDXJSON(r io.ReadSeeker, report types.Report) (VEX, error) { if err != nil { return nil, xerrors.Errorf("json decode error: %w", err) } - if report.ArtifactType != ftypes.ArtifactCycloneDX { + if report.ArtifactType != artifact.TypeCycloneDX { return nil, xerrors.New("CycloneDX VEX can be used with CycloneDX SBOM") } return newCycloneDX(report.BOM, vex), nil diff --git a/pkg/vex/vex_test.go b/pkg/vex/vex_test.go index 77d2aff3c63e..ad385b63596e 100644 --- a/pkg/vex/vex_test.go +++ b/pkg/vex/vex_test.go @@ -1,6 +1,7 @@ package vex_test import ( + "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/sbom/core" "os" "testing" @@ -135,7 +136,7 @@ func TestVEX_Filter(t *testing.T) { fields: fields{ filePath: "testdata/cyclonedx.json", report: types.Report{ - ArtifactType: ftypes.ArtifactCycloneDX, + ArtifactType: artifact.TypeCycloneDX, BOM: &core.BOM{ SerialNumber: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", Version: 1, @@ -218,7 +219,7 @@ func TestVEX_Filter(t *testing.T) { fields: fields{ filePath: "testdata/cyclonedx.json", report: types.Report{ - ArtifactType: ftypes.ArtifactCycloneDX, + ArtifactType: artifact.TypeCycloneDX, BOM: &core.BOM{ SerialNumber: "urn:uuid:wrong", Version: 1, @@ -378,7 +379,7 @@ func newTestBOM() *core.BOM { Root: true, Type: core.TypeContainerImage, Name: "debian:12", - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: packageurl.TypeOCI, Name: "debian", @@ -405,7 +406,7 @@ func newTestBOM2() *core.BOM { Root: true, Type: core.TypeContainerImage, Name: "ubuntu:24.04", - PkgID: core.PkgID{ + PkgIdentifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ Type: packageurl.TypeOCI, Name: "ubuntu",