diff --git a/integration/registry_test.go b/integration/registry_test.go index bd6046292a..4a21e574f9 100644 --- a/integration/registry_test.go +++ b/integration/registry_test.go @@ -27,6 +27,7 @@ import ( "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" + "github.com/aquasecurity/trivy/internal/testutil" "github.com/aquasecurity/trivy/pkg/types" ) @@ -249,7 +250,7 @@ func TestRegistry(t *testing.T) { runTest(t, osArgs, tt.golden, types.FormatJSON, runOptions{ wantErr: tt.wantErr, fakeUUID: "3ff14136-e09f-4df9-80ea-%012d", - override: overrideFuncs(overrideUID, func(_ *testing.T, want, got *types.Report) { + override: overrideFuncs(overrideUID, func(t *testing.T, want, got *types.Report) { // Exclude ArtifactID from comparison because registry tests use random ports // (e.g., localhost:54321/alpine:3.10), which causes RepoTags and the calculated // Artifact ID to vary on each test run. @@ -258,6 +259,7 @@ func TestRegistry(t *testing.T) { want.ArtifactName = s want.Metadata.RepoTags = []string{s} + want.Metadata.Reference = testutil.MustParseReference(t, s) for i := range want.Results { want.Results[i].Target = fmt.Sprintf("%s (%s)", s, tt.os) } diff --git a/integration/testdata/almalinux-8.json.golden b/integration/testdata/almalinux-8.json.golden index 49415b37b3..80f09d2bbb 100644 --- a/integration/testdata/almalinux-8.json.golden +++ b/integration/testdata/almalinux-8.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:almalinux-8" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:almalinux-8", "ImageConfig": { "architecture": "amd64", "container": "a467f67a48d469e1975b7414f33f2cf87121d4cc59d2ee029ea58e6b81774769", diff --git a/integration/testdata/alpine-310.json.golden b/integration/testdata/alpine-310.json.golden index ab3dc6c641..374a7d8918 100644 --- a/integration/testdata/alpine-310.json.golden +++ b/integration/testdata/alpine-310.json.golden @@ -19,6 +19,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:alpine-310" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:alpine-310", "ImageConfig": { "architecture": "amd64", "container": "0a80155a31551fcc1a36fccbbda79fcd3f0b1c7d270653d00310e6e2217c57e6", diff --git a/integration/testdata/alpine-39-high-critical.json.golden b/integration/testdata/alpine-39-high-critical.json.golden index ef79355959..ae6fbb6505 100644 --- a/integration/testdata/alpine-39-high-critical.json.golden +++ b/integration/testdata/alpine-39-high-critical.json.golden @@ -19,6 +19,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:alpine-39" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:alpine-39", "ImageConfig": { "architecture": "amd64", "container": "c10d36fa368a7ea673683682666758adf35efe98e10989505f4f566b5b18538f", diff --git a/integration/testdata/alpine-39-ignore-cveids.json.golden b/integration/testdata/alpine-39-ignore-cveids.json.golden index cc8d2c9682..a6a6720b8c 100644 --- a/integration/testdata/alpine-39-ignore-cveids.json.golden +++ b/integration/testdata/alpine-39-ignore-cveids.json.golden @@ -19,6 +19,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:alpine-39" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:alpine-39", "ImageConfig": { "architecture": "amd64", "container": "c10d36fa368a7ea673683682666758adf35efe98e10989505f4f566b5b18538f", diff --git a/integration/testdata/alpine-39-skip.json.golden b/integration/testdata/alpine-39-skip.json.golden index 6ea8bf366a..35dc24024c 100644 --- a/integration/testdata/alpine-39-skip.json.golden +++ b/integration/testdata/alpine-39-skip.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:alpine-39" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:alpine-39", "ImageConfig": { "architecture": "amd64", "container": "c10d36fa368a7ea673683682666758adf35efe98e10989505f4f566b5b18538f", diff --git a/integration/testdata/alpine-39.json.golden b/integration/testdata/alpine-39.json.golden index a5804b27d8..7f1d8cdf41 100644 --- a/integration/testdata/alpine-39.json.golden +++ b/integration/testdata/alpine-39.json.golden @@ -19,6 +19,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:alpine-39" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:alpine-39", "ImageConfig": { "architecture": "amd64", "container": "c10d36fa368a7ea673683682666758adf35efe98e10989505f4f566b5b18538f", diff --git a/integration/testdata/alpine-distroless.json.golden b/integration/testdata/alpine-distroless.json.golden index b0c28affe4..b18922f76a 100644 --- a/integration/testdata/alpine-distroless.json.golden +++ b/integration/testdata/alpine-distroless.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:alpine-distroless" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:alpine-distroless", "ImageConfig": { "architecture": "amd64", "author": "github.com/chainguard-dev/apko", diff --git a/integration/testdata/amazon-1.json.golden b/integration/testdata/amazon-1.json.golden index 517fd45961..ce286aa17f 100644 --- a/integration/testdata/amazon-1.json.golden +++ b/integration/testdata/amazon-1.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:amazon-1" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:amazon-1", "ImageConfig": { "architecture": "amd64", "container": "ef1b126795001e9b4bdc14a01180e4d8146282d279f53e05adfaa8195ecda20e", diff --git a/integration/testdata/amazon-2.json.golden b/integration/testdata/amazon-2.json.golden index e570abc852..53c44219c4 100644 --- a/integration/testdata/amazon-2.json.golden +++ b/integration/testdata/amazon-2.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:amazon-2" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:amazon-2", "ImageConfig": { "architecture": "amd64", "container": "e020a5508b9f809b29659128692cd634e3d4fba3f2c13d2029d797317b5c3a56", diff --git a/integration/testdata/busybox-with-lockfile.json.golden b/integration/testdata/busybox-with-lockfile.json.golden index e4349a65d8..979d99c5fd 100644 --- a/integration/testdata/busybox-with-lockfile.json.golden +++ b/integration/testdata/busybox-with-lockfile.json.golden @@ -15,6 +15,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:busybox-with-lockfile" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:busybox-with-lockfile", "ImageConfig": { "architecture": "amd64", "created": "2022-06-07T04:24:40.230164Z", diff --git a/integration/testdata/centos-6.json.golden b/integration/testdata/centos-6.json.golden index 3464642c78..96007a044d 100644 --- a/integration/testdata/centos-6.json.golden +++ b/integration/testdata/centos-6.json.golden @@ -19,6 +19,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:centos-6" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:centos-6", "ImageConfig": { "architecture": "amd64", "author": "https://github.com/CentOS/sig-cloud-instance-images", diff --git a/integration/testdata/centos-7-ignore-unfixed.json.golden b/integration/testdata/centos-7-ignore-unfixed.json.golden index e886776c57..c9d98c5c0a 100644 --- a/integration/testdata/centos-7-ignore-unfixed.json.golden +++ b/integration/testdata/centos-7-ignore-unfixed.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:centos-7" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:centos-7", "ImageConfig": { "architecture": "amd64", "container": "cc6043a787f6d1c7ae3e121ebdf1c4478186336aa7274871780a0a7bcc3a061a", diff --git a/integration/testdata/centos-7-medium.json.golden b/integration/testdata/centos-7-medium.json.golden index adfd1c8438..13dc62c9a7 100644 --- a/integration/testdata/centos-7-medium.json.golden +++ b/integration/testdata/centos-7-medium.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:centos-7" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:centos-7", "ImageConfig": { "architecture": "amd64", "container": "cc6043a787f6d1c7ae3e121ebdf1c4478186336aa7274871780a0a7bcc3a061a", diff --git a/integration/testdata/centos-7.json.golden b/integration/testdata/centos-7.json.golden index 83a0c37947..f2d0bde3af 100644 --- a/integration/testdata/centos-7.json.golden +++ b/integration/testdata/centos-7.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:centos-7" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:centos-7", "ImageConfig": { "architecture": "amd64", "container": "cc6043a787f6d1c7ae3e121ebdf1c4478186336aa7274871780a0a7bcc3a061a", diff --git a/integration/testdata/debian-buster-ignore-unfixed.json.golden b/integration/testdata/debian-buster-ignore-unfixed.json.golden index 4fcbe139b2..7bab1028c3 100644 --- a/integration/testdata/debian-buster-ignore-unfixed.json.golden +++ b/integration/testdata/debian-buster-ignore-unfixed.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:debian-buster" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:debian-buster", "ImageConfig": { "architecture": "amd64", "container": "cbb6a20ddb7dedfeee41aeb21e9780f14afbb0f47a6b1ffa514a1822f45d0a51", diff --git a/integration/testdata/debian-buster.json.golden b/integration/testdata/debian-buster.json.golden index cdb5ad4494..91cfb21f95 100644 --- a/integration/testdata/debian-buster.json.golden +++ b/integration/testdata/debian-buster.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:debian-buster" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:debian-buster", "ImageConfig": { "architecture": "amd64", "container": "cbb6a20ddb7dedfeee41aeb21e9780f14afbb0f47a6b1ffa514a1822f45d0a51", diff --git a/integration/testdata/debian-stretch.json.golden b/integration/testdata/debian-stretch.json.golden index cb9f5da738..b6e7e3a2d8 100644 --- a/integration/testdata/debian-stretch.json.golden +++ b/integration/testdata/debian-stretch.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:debian-stretch" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:debian-stretch", "ImageConfig": { "architecture": "amd64", "container": "957bc0b73d29f0e1030fec9c63f81d3e81baa610cffcc9c574b14fee6d1821ae", diff --git a/integration/testdata/distroless-base.json.golden b/integration/testdata/distroless-base.json.golden index 36f34f576e..765e86173c 100644 --- a/integration/testdata/distroless-base.json.golden +++ b/integration/testdata/distroless-base.json.golden @@ -19,6 +19,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:distroless-base" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:distroless-base", "ImageConfig": { "architecture": "amd64", "author": "Bazel", diff --git a/integration/testdata/distroless-python27.json.golden b/integration/testdata/distroless-python27.json.golden index 01f55663b9..20deb3bfef 100644 --- a/integration/testdata/distroless-python27.json.golden +++ b/integration/testdata/distroless-python27.json.golden @@ -21,6 +21,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:distroless-python27" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:distroless-python27", "ImageConfig": { "architecture": "amd64", "author": "Bazel", diff --git a/integration/testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl b/integration/testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl index 9af83c45f0..797174e664 100644 --- a/integration/testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl +++ b/integration/testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl @@ -1 +1 @@ -{"payloadType":"application/vnd.in-toto+json","payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2N5Y2xvbmVkeC5vcmcvYm9tIiwic3ViamVjdCI6W3sibmFtZSI6ImluZGV4LmRvY2tlci5pby9saWJyYXJ5L2NlbnRvcyIsImRpZ2VzdCI6eyJzaGEyNTYiOiJiZTY1ZjQ4OGI3NzY0YWQzNjM4ZjIzNmI3YjUxNWIzNjc4MzY5YTUxMjRjNDdiOGQzMjkxNmQ2NDg3NDE4ZWE0In19XSwicHJlZGljYXRlIjp7ImJvbUZvcm1hdCI6IkN5Y2xvbmVEWCIsInNwZWNWZXJzaW9uIjoiMS40Iiwic2VyaWFsTnVtYmVyIjoidXJuOnV1aWQ6MTQ1NWMwMmQtNjRjYS00NTNlLWE1ZGYtZGRmYjcwYTdjODA0IiwidmVyc2lvbiI6MSwibWV0YWRhdGEiOnsidGltZXN0YW1wIjoiMjAyMi0wNi0xNFQxNTowODo0OCswMDowMCIsInRvb2xzIjpbeyJ2ZW5kb3IiOiJhcXVhc2VjdXJpdHkiLCJuYW1lIjoidHJpdnkiLCJ2ZXJzaW9uIjoiZGV2In1dLCJjb21wb25lbnQiOnsiYm9tLXJlZiI6ImQwZDQxZTMwLTk2NTAtNDg5ZC05NDhkLTQyNWZmMmVkNjNkMiIsInR5cGUiOiJjb250YWluZXIiLCJuYW1lIjoiaW50ZWdyYXRpb24vdGVzdGRhdGEvZml4dHVyZXMvaW1hZ2VzL2NlbnRvcy03LnRhci5neiIsInByb3BlcnRpZXMiOlt7Im5hbWUiOiJhcXVhc2VjdXJpdHk6dHJpdnk6U2NoZW1hVmVyc2lvbiIsInZhbHVlIjoiMiJ9LHsibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpJbWFnZUlEIiwidmFsdWUiOiJzaGEyNTY6ZjFjYjdjN2Q1OGI3M2VhYzg1OWMzOTU4ODJlZWM0OWQ1MDY1MTI0NGUzNDJjZDZjNjhhNWM3ODA5Nzg1ZjQyNyJ9LHsibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpEaWZmSUQiLCJ2YWx1ZSI6InNoYTI1Njo4OTE2OWQ4N2RiZTJiNzJiYTQyYmZiYjM1NzljOTU3MzIyYmFjYTI4ZTAzYTFlNTU4MDc2NTQyYTFjMWIyYjRhIn0seyJuYW1lIjoiYXF1YXNlY3VyaXR5OnRyaXZ5OlJlcG9UYWciLCJ2YWx1ZSI6ImdoY3IuaW8vYXF1YXNlY3VyaXR5L3RyaXZ5LXRlc3QtaW1hZ2VzOmNlbnRvcy03In1dfX0sImNvbXBvbmVudHMiOlt7ImJvbS1yZWYiOiJwa2c6cnBtL2NlbnRvcy9iYXNoQDQuMi40Ni0zMS5lbDc/YXJjaD14ODZfNjQmZGlzdHJvPWNlbnRvcy03LjYuMTgxMCIsInR5cGUiOiJsaWJyYXJ5IiwibmFtZSI6ImJhc2giLCJ2ZXJzaW9uIjoiNC4yLjQ2LTMxLmVsNyIsImxpY2Vuc2VzIjpbeyJleHByZXNzaW9uIjoiR1BMdjMrIn1dLCJwdXJsIjoicGtnOnJwbS9jZW50b3MvYmFzaEA0LjIuNDYtMzEuZWw3P2FyY2g9eDg2XzY0JmRpc3Rybz1jZW50b3MtNy42LjE4MTAiLCJwcm9wZXJ0aWVzIjpbeyJuYW1lIjoiYXF1YXNlY3VyaXR5OnRyaXZ5OlBrZ0lEIiwidmFsdWUiOiJiYXNoQDQuMi40Ni0zMS5lbDcueDg2XzY0In0seyJuYW1lIjoiYXF1YXNlY3VyaXR5OnRyaXZ5OlNyY05hbWUiLCJ2YWx1ZSI6ImJhc2gifSx7Im5hbWUiOiJhcXVhc2VjdXJpdHk6dHJpdnk6U3JjVmVyc2lvbiIsInZhbHVlIjoiNC4yLjQ2In0seyJuYW1lIjoiYXF1YXNlY3VyaXR5OnRyaXZ5OlNyY1JlbGVhc2UiLCJ2YWx1ZSI6IjMxLmVsNyJ9LHsibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpMYXllckRpZ2VzdCIsInZhbHVlIjoic2hhMjU2OmFjOTIwODIwN2FkYWFjM2E0OGU1NGE0ZGM2YjQ5YzY5ZTc4YzMwNzJkMmIzYWRkN2VmZGFiZjgxNGRiMjEzM2IifSx7Im5hbWUiOiJhcXVhc2VjdXJpdHk6dHJpdnk6TGF5ZXJEaWZmSUQiLCJ2YWx1ZSI6InNoYTI1Njo4OTE2OWQ4N2RiZTJiNzJiYTQyYmZiYjM1NzljOTU3MzIyYmFjYTI4ZTAzYTFlNTU4MDc2NTQyYTFjMWIyYjRhIn1dfSx7ImJvbS1yZWYiOiJwa2c6cnBtL2NlbnRvcy9vcGVuc3NsLWxpYnNAMS4wLjJrLTE2LmVsNz9hcmNoPXg4Nl82NCZlcG9jaD0xJmRpc3Rybz1jZW50b3MtNy42LjE4MTAiLCJ0eXBlIjoibGlicmFyeSIsIm5hbWUiOiJvcGVuc3NsLWxpYnMiLCJ2ZXJzaW9uIjoiMS4wLjJrLTE2LmVsNyIsImxpY2Vuc2VzIjpbeyJleHByZXNzaW9uIjoiT3BlblNTTCJ9XSwicHVybCI6InBrZzpycG0vY2VudG9zL29wZW5zc2wtbGlic0AxLjAuMmstMTYuZWw3P2FyY2g9eDg2XzY0JmVwb2NoPTEmZGlzdHJvPWNlbnRvcy03LjYuMTgxMCIsInByb3BlcnRpZXMiOlt7Im5hbWUiOiJhcXVhc2VjdXJpdHk6dHJpdnk6UGtnSUQiLCJ2YWx1ZSI6Im9wZW5zc2wtbGlic0AxLjAuMmstMTYuZWw3Lng4Nl82NCJ9LHsibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpTcmNOYW1lIiwidmFsdWUiOiJvcGVuc3NsIn0seyJuYW1lIjoiYXF1YXNlY3VyaXR5OnRyaXZ5OlNyY1ZlcnNpb24iLCJ2YWx1ZSI6IjEuMC4yayJ9LHsibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpTcmNSZWxlYXNlIiwidmFsdWUiOiIxNi5lbDcifSx7Im5hbWUiOiJhcXVhc2VjdXJpdHk6dHJpdnk6U3JjRXBvY2giLCJ2YWx1ZSI6IjEifSx7Im5hbWUiOiJhcXVhc2VjdXJpdHk6dHJpdnk6TGF5ZXJEaWdlc3QiLCJ2YWx1ZSI6InNoYTI1NjphYzkyMDgyMDdhZGFhYzNhNDhlNTRhNGRjNmI0OWM2OWU3OGMzMDcyZDJiM2FkZDdlZmRhYmY4MTRkYjIxMzNiIn0seyJuYW1lIjoiYXF1YXNlY3VyaXR5OnRyaXZ5OkxheWVyRGlmZklEIiwidmFsdWUiOiJzaGEyNTY6ODkxNjlkODdkYmUyYjcyYmE0MmJmYmIzNTc5Yzk1NzMyMmJhY2EyOGUwM2ExZTU1ODA3NjU0MmExYzFiMmI0YSJ9XX0seyJib20tcmVmIjoiMDE3NWY3MzItZGY5ZC00YmI4LTlmNTYtODcwODk4ZTNmZjg5IiwidHlwZSI6Im9wZXJhdGluZy1zeXN0ZW0iLCJuYW1lIjoiY2VudG9zIiwidmVyc2lvbiI6IjcuNi4xODEwIiwicHJvcGVydGllcyI6W3sibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpUeXBlIiwidmFsdWUiOiJjZW50b3MifSx7Im5hbWUiOiJhcXVhc2VjdXJpdHk6dHJpdnk6Q2xhc3MiLCJ2YWx1ZSI6Im9zLXBrZ3MifV19XSwiZGVwZW5kZW5jaWVzIjpbeyJyZWYiOiIwMTc1ZjczMi1kZjlkLTRiYjgtOWY1Ni04NzA4OThlM2ZmODkiLCJkZXBlbmRzT24iOlsicGtnOnJwbS9jZW50b3MvYmFzaEA0LjIuNDYtMzEuZWw3P2FyY2g9eDg2XzY0JmRpc3Rybz1jZW50b3MtNy42LjE4MTAiLCJwa2c6cnBtL2NlbnRvcy9vcGVuc3NsLWxpYnNAMS4wLjJrLTE2LmVsNz9hcmNoPXg4Nl82NCZlcG9jaD0xJmRpc3Rybz1jZW50b3MtNy42LjE4MTAiXX0seyJyZWYiOiJkMGQ0MWUzMC05NjUwLTQ4OWQtOTQ4ZC00MjVmZjJlZDYzZDIiLCJkZXBlbmRzT24iOlsiMDE3NWY3MzItZGY5ZC00YmI4LTlmNTYtODcwODk4ZTNmZjg5Il19XX19Cg==","signatures":[{"keyid":"","sig":"MEUCIQCtj78dipe+yzdlIsmwjn9QeaBTAPQacwIJAWfnrtp7FwIgcViOUgPA0WFYjimrIl7vbygdSpduM+ZzY3cqrDciH1U="}]} +{"payloadType":"application/vnd.in-toto+json","payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2N5Y2xvbmVkeC5vcmcvYm9tIiwic3ViamVjdCI6W3sibmFtZSI6ImluZGV4LmRvY2tlci5pby9saWJyYXJ5L2NlbnRvcyIsImRpZ2VzdCI6eyJzaGEyNTYiOiJiZTY1ZjQ4OGI3NzY0YWQzNjM4ZjIzNmI3YjUxNWIzNjc4MzY5YTUxMjRjNDdiOGQzMjkxNmQ2NDg3NDE4ZWE0In19XSwicHJlZGljYXRlIjp7ImJvbUZvcm1hdCI6IkN5Y2xvbmVEWCIsInNwZWNWZXJzaW9uIjoiMS40Iiwic2VyaWFsTnVtYmVyIjoidXJuOnV1aWQ6MTQ1NWMwMmQtNjRjYS00NTNlLWE1ZGYtZGRmYjcwYTdjODA0IiwidmVyc2lvbiI6MSwibWV0YWRhdGEiOnsidGltZXN0YW1wIjoiMjAyMi0wNi0xNFQxNTowODo0OCswMDowMCIsInRvb2xzIjpbeyJ2ZW5kb3IiOiJhcXVhc2VjdXJpdHkiLCJuYW1lIjoidHJpdnkiLCJ2ZXJzaW9uIjoiZGV2In1dLCJjb21wb25lbnQiOnsiYm9tLXJlZiI6ImQwZDQxZTMwLTk2NTAtNDg5ZC05NDhkLTQyNWZmMmVkNjNkMiIsInR5cGUiOiJjb250YWluZXIiLCJuYW1lIjoiaW50ZWdyYXRpb24vdGVzdGRhdGEvZml4dHVyZXMvaW1hZ2VzL2NlbnRvcy03LnRhci5neiIsInByb3BlcnRpZXMiOlt7Im5hbWUiOiJhcXVhc2VjdXJpdHk6dHJpdnk6U2NoZW1hVmVyc2lvbiIsInZhbHVlIjoiMiJ9LHsibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpJbWFnZUlEIiwidmFsdWUiOiJzaGEyNTY6ZjFjYjdjN2Q1OGI3M2VhYzg1OWMzOTU4ODJlZWM0OWQ1MDY1MTI0NGUzNDJjZDZjNjhhNWM3ODA5Nzg1ZjQyNyJ9LHsibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpEaWZmSUQiLCJ2YWx1ZSI6InNoYTI1Njo4OTE2OWQ4N2RiZTJiNzJiYTQyYmZiYjM1NzljOTU3MzIyYmFjYTI4ZTAzYTFlNTU4MDc2NTQyYTFjMWIyYjRhIn0seyJuYW1lIjoiYXF1YXNlY3VyaXR5OnRyaXZ5OlJlcG9UYWciLCJ2YWx1ZSI6ImdoY3IuaW8vYXF1YXNlY3VyaXR5L3RyaXZ5LXRlc3QtaW1hZ2VzOmNlbnRvcy03In0seyJuYW1lIjoiYXF1YXNlY3VyaXR5OnRyaXZ5OlJlZmVyZW5jZSIsInZhbHVlIjoiZ2hjci5pby9hcXVhc2VjdXJpdHkvdHJpdnktdGVzdC1pbWFnZXM6Y2VudG9zLTcifV19fSwiY29tcG9uZW50cyI6W3siYm9tLXJlZiI6InBrZzpycG0vY2VudG9zL2Jhc2hANC4yLjQ2LTMxLmVsNz9hcmNoPXg4Nl82NCZkaXN0cm89Y2VudG9zLTcuNi4xODEwIiwidHlwZSI6ImxpYnJhcnkiLCJuYW1lIjoiYmFzaCIsInZlcnNpb24iOiI0LjIuNDYtMzEuZWw3IiwibGljZW5zZXMiOlt7ImV4cHJlc3Npb24iOiJHUEx2MysifV0sInB1cmwiOiJwa2c6cnBtL2NlbnRvcy9iYXNoQDQuMi40Ni0zMS5lbDc/YXJjaD14ODZfNjQmZGlzdHJvPWNlbnRvcy03LjYuMTgxMCIsInByb3BlcnRpZXMiOlt7Im5hbWUiOiJhcXVhc2VjdXJpdHk6dHJpdnk6UGtnSUQiLCJ2YWx1ZSI6ImJhc2hANC4yLjQ2LTMxLmVsNy54ODZfNjQifSx7Im5hbWUiOiJhcXVhc2VjdXJpdHk6dHJpdnk6U3JjTmFtZSIsInZhbHVlIjoiYmFzaCJ9LHsibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpTcmNWZXJzaW9uIiwidmFsdWUiOiI0LjIuNDYifSx7Im5hbWUiOiJhcXVhc2VjdXJpdHk6dHJpdnk6U3JjUmVsZWFzZSIsInZhbHVlIjoiMzEuZWw3In0seyJuYW1lIjoiYXF1YXNlY3VyaXR5OnRyaXZ5OkxheWVyRGlnZXN0IiwidmFsdWUiOiJzaGEyNTY6YWM5MjA4MjA3YWRhYWMzYTQ4ZTU0YTRkYzZiNDljNjllNzhjMzA3MmQyYjNhZGQ3ZWZkYWJmODE0ZGIyMTMzYiJ9LHsibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpMYXllckRpZmZJRCIsInZhbHVlIjoic2hhMjU2Ojg5MTY5ZDg3ZGJlMmI3MmJhNDJiZmJiMzU3OWM5NTczMjJiYWNhMjhlMDNhMWU1NTgwNzY1NDJhMWMxYjJiNGEifV19LHsiYm9tLXJlZiI6InBrZzpycG0vY2VudG9zL29wZW5zc2wtbGlic0AxLjAuMmstMTYuZWw3P2FyY2g9eDg2XzY0JmVwb2NoPTEmZGlzdHJvPWNlbnRvcy03LjYuMTgxMCIsInR5cGUiOiJsaWJyYXJ5IiwibmFtZSI6Im9wZW5zc2wtbGlicyIsInZlcnNpb24iOiIxLjAuMmstMTYuZWw3IiwibGljZW5zZXMiOlt7ImV4cHJlc3Npb24iOiJPcGVuU1NMIn1dLCJwdXJsIjoicGtnOnJwbS9jZW50b3Mvb3BlbnNzbC1saWJzQDEuMC4yay0xNi5lbDc/YXJjaD14ODZfNjQmZXBvY2g9MSZkaXN0cm89Y2VudG9zLTcuNi4xODEwIiwicHJvcGVydGllcyI6W3sibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpQa2dJRCIsInZhbHVlIjoib3BlbnNzbC1saWJzQDEuMC4yay0xNi5lbDcueDg2XzY0In0seyJuYW1lIjoiYXF1YXNlY3VyaXR5OnRyaXZ5OlNyY05hbWUiLCJ2YWx1ZSI6Im9wZW5zc2wifSx7Im5hbWUiOiJhcXVhc2VjdXJpdHk6dHJpdnk6U3JjVmVyc2lvbiIsInZhbHVlIjoiMS4wLjJrIn0seyJuYW1lIjoiYXF1YXNlY3VyaXR5OnRyaXZ5OlNyY1JlbGVhc2UiLCJ2YWx1ZSI6IjE2LmVsNyJ9LHsibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpTcmNFcG9jaCIsInZhbHVlIjoiMSJ9LHsibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpMYXllckRpZ2VzdCIsInZhbHVlIjoic2hhMjU2OmFjOTIwODIwN2FkYWFjM2E0OGU1NGE0ZGM2YjQ5YzY5ZTc4YzMwNzJkMmIzYWRkN2VmZGFiZjgxNGRiMjEzM2IifSx7Im5hbWUiOiJhcXVhc2VjdXJpdHk6dHJpdnk6TGF5ZXJEaWZmSUQiLCJ2YWx1ZSI6InNoYTI1Njo4OTE2OWQ4N2RiZTJiNzJiYTQyYmZiYjM1NzljOTU3MzIyYmFjYTI4ZTAzYTFlNTU4MDc2NTQyYTFjMWIyYjRhIn1dfSx7ImJvbS1yZWYiOiIwMTc1ZjczMi1kZjlkLTRiYjgtOWY1Ni04NzA4OThlM2ZmODkiLCJ0eXBlIjoib3BlcmF0aW5nLXN5c3RlbSIsIm5hbWUiOiJjZW50b3MiLCJ2ZXJzaW9uIjoiNy42LjE4MTAiLCJwcm9wZXJ0aWVzIjpbeyJuYW1lIjoiYXF1YXNlY3VyaXR5OnRyaXZ5OlR5cGUiLCJ2YWx1ZSI6ImNlbnRvcyJ9LHsibmFtZSI6ImFxdWFzZWN1cml0eTp0cml2eTpDbGFzcyIsInZhbHVlIjoib3MtcGtncyJ9XX1dLCJkZXBlbmRlbmNpZXMiOlt7InJlZiI6IjAxNzVmNzMyLWRmOWQtNGJiOC05ZjU2LTg3MDg5OGUzZmY4OSIsImRlcGVuZHNPbiI6WyJwa2c6cnBtL2NlbnRvcy9iYXNoQDQuMi40Ni0zMS5lbDc/YXJjaD14ODZfNjQmZGlzdHJvPWNlbnRvcy03LjYuMTgxMCIsInBrZzpycG0vY2VudG9zL29wZW5zc2wtbGlic0AxLjAuMmstMTYuZWw3P2FyY2g9eDg2XzY0JmVwb2NoPTEmZGlzdHJvPWNlbnRvcy03LjYuMTgxMCJdfSx7InJlZiI6ImQwZDQxZTMwLTk2NTAtNDg5ZC05NDhkLTQyNWZmMmVkNjNkMiIsImRlcGVuZHNPbiI6WyIwMTc1ZjczMi1kZjlkLTRiYjgtOWY1Ni04NzA4OThlM2ZmODkiXX1dfX0K","signatures":[{"keyid":"","sig":"MEUCIQCtj78dipe+yzdlIsmwjn9QeaBTAPQacwIJAWfnrtp7FwIgcViOUgPA0WFYjimrIl7vbygdSpduM+ZzY3cqrDciH1U="}]} diff --git a/integration/testdata/fixtures/sbom/centos-7-cyclonedx.json b/integration/testdata/fixtures/sbom/centos-7-cyclonedx.json index 2fa8753531..81d4a72e24 100644 --- a/integration/testdata/fixtures/sbom/centos-7-cyclonedx.json +++ b/integration/testdata/fixtures/sbom/centos-7-cyclonedx.json @@ -32,6 +32,10 @@ { "name": "aquasecurity:trivy:RepoTag", "value": "ghcr.io/aquasecurity/trivy-test-images:centos-7" + }, + { + "name": "aquasecurity:trivy:Reference", + "value": "ghcr.io/aquasecurity/trivy-test-images:centos-7" } ] } diff --git a/integration/testdata/fixtures/sbom/centos-7-spdx.json b/integration/testdata/fixtures/sbom/centos-7-spdx.json index d70f39f5e4..9ae0ec0cf1 100644 --- a/integration/testdata/fixtures/sbom/centos-7-spdx.json +++ b/integration/testdata/fixtures/sbom/centos-7-spdx.json @@ -17,7 +17,8 @@ "SchemaVersion: 2", "ImageID: sha256:f1cb7c7d58b73eac859c395882eec49d50651244e342cd6c68a5c7809785f427", "DiffID: sha256:89169d87dbe2b72ba42bfbb3579c957322baca28e03a1e558076542a1c1b2b4a", - "RepoTag: ghcr.io/aquasecurity/trivy-test-images:centos-7" + "RepoTag: ghcr.io/aquasecurity/trivy-test-images:centos-7", + "Reference: ghcr.io/aquasecurity/trivy-test-images:centos-7" ], "filesAnalyzed": false, "name": "integration/testdata/fixtures/images/centos-7.tar.gz" diff --git a/integration/testdata/fixtures/sbom/centos-7-spdx.txt b/integration/testdata/fixtures/sbom/centos-7-spdx.txt index 0887ba160d..fc57bb0d82 100644 --- a/integration/testdata/fixtures/sbom/centos-7-spdx.txt +++ b/integration/testdata/fixtures/sbom/centos-7-spdx.txt @@ -16,6 +16,7 @@ PackageAttributionText: SchemaVersion: 2 PackageAttributionText: ImageID: sha256:f1cb7c7d58b73eac859c395882eec49d50651244e342cd6c68a5c7809785f427 PackageAttributionText: DiffID: sha256:89169d87dbe2b72ba42bfbb3579c957322baca28e03a1e558076542a1c1b2b4a PackageAttributionText: RepoTag: ghcr.io/aquasecurity/trivy-test-images:centos-7 +PackageAttributionText: Reference: ghcr.io/aquasecurity/trivy-test-images:centos-7 ##### Package: centos diff --git a/integration/testdata/fluentd-gems.json.golden b/integration/testdata/fluentd-gems.json.golden index c7c0c9dcb2..1c2151de5a 100644 --- a/integration/testdata/fluentd-gems.json.golden +++ b/integration/testdata/fluentd-gems.json.golden @@ -23,6 +23,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:fluentd-multiple-lockfiles" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:fluentd-multiple-lockfiles", "ImageConfig": { "architecture": "amd64", "container": "232f3fc7ddffd71dc3ff52c6c0c3a5feea2f51acffd9b53850a8fc6f1a15319a", diff --git a/integration/testdata/fluentd-multiple-lockfiles.cdx.json.golden b/integration/testdata/fluentd-multiple-lockfiles.cdx.json.golden index 19e4d7ba34..00d3852d84 100644 --- a/integration/testdata/fluentd-multiple-lockfiles.cdx.json.golden +++ b/integration/testdata/fluentd-multiple-lockfiles.cdx.json.golden @@ -52,6 +52,10 @@ "name": "aquasecurity:trivy:ImageID", "value": "sha256:5a992077baba51b97f27591a10d54d2f2723dc9c81a3fe419e261023f2554933" }, + { + "name": "aquasecurity:trivy:Reference", + "value": "ghcr.io/aquasecurity/trivy-test-images:fluentd-multiple-lockfiles" + }, { "name": "aquasecurity:trivy:RepoTag", "value": "ghcr.io/aquasecurity/trivy-test-images:fluentd-multiple-lockfiles" diff --git a/integration/testdata/mariner-1.0.json.golden b/integration/testdata/mariner-1.0.json.golden index 5d23f94b03..6ffa861acf 100644 --- a/integration/testdata/mariner-1.0.json.golden +++ b/integration/testdata/mariner-1.0.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:mariner-1.0" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:mariner-1.0", "ImageConfig": { "architecture": "amd64", "created": "2022-01-27T01:19:38.526301656Z", diff --git a/integration/testdata/opensuse-leap-151.json.golden b/integration/testdata/opensuse-leap-151.json.golden index bc66a3d533..bad7923d66 100644 --- a/integration/testdata/opensuse-leap-151.json.golden +++ b/integration/testdata/opensuse-leap-151.json.golden @@ -19,6 +19,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:opensuse-leap-151" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:opensuse-leap-151", "ImageConfig": { "architecture": "amd64", "author": "Fabian Vogt \u003cfvogt@suse.com\u003e", diff --git a/integration/testdata/opensuse-tumbleweed.json.golden b/integration/testdata/opensuse-tumbleweed.json.golden index 9cb89faf18..b197c16589 100644 --- a/integration/testdata/opensuse-tumbleweed.json.golden +++ b/integration/testdata/opensuse-tumbleweed.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:opensuse-tumbleweed" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:opensuse-tumbleweed", "ImageConfig": { "architecture": "amd64", "author": "Fabian Vogt \u003cfvogt@suse.com\u003e", diff --git a/integration/testdata/oraclelinux-8.json.golden b/integration/testdata/oraclelinux-8.json.golden index 77b7dfce6e..ccb25fda4d 100644 --- a/integration/testdata/oraclelinux-8.json.golden +++ b/integration/testdata/oraclelinux-8.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:oraclelinux-8" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:oraclelinux-8", "ImageConfig": { "architecture": "amd64", "author": "Oracle Linux Product Team \u003col-ovm-info_ww@oracle.com\u003e", diff --git a/integration/testdata/photon-30.json.golden b/integration/testdata/photon-30.json.golden index 2b58bbaa8d..0facfa2d67 100644 --- a/integration/testdata/photon-30.json.golden +++ b/integration/testdata/photon-30.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:photon-30" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:photon-30", "ImageConfig": { "architecture": "amd64", "container": "ed27e7f1fbd8ef9d3ea89947f682907e9a65a8e51bbe2e0eba60db6e69213848", diff --git a/integration/testdata/rockylinux-8.json.golden b/integration/testdata/rockylinux-8.json.golden index 5c13f02189..093635e529 100644 --- a/integration/testdata/rockylinux-8.json.golden +++ b/integration/testdata/rockylinux-8.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:rockylinux-8" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:rockylinux-8", "ImageConfig": { "architecture": "amd64", "container": "16458df10693f731fae0492f791a5e4b725245c35cf28c7fca00982219d7bdf3", diff --git a/integration/testdata/sl-micro-rancher5.4.json.golden b/integration/testdata/sl-micro-rancher5.4.json.golden index 161213dc26..ef6b01a7db 100644 --- a/integration/testdata/sl-micro-rancher5.4.json.golden +++ b/integration/testdata/sl-micro-rancher5.4.json.golden @@ -18,6 +18,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:sle-micro-rancher-5.4_ndb" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:sle-micro-rancher-5.4_ndb", "ImageConfig": { "architecture": "amd64", "author": "SUSE LLC (https://www.suse.com/)", diff --git a/integration/testdata/spring4shell-jre11.json.golden b/integration/testdata/spring4shell-jre11.json.golden index 7fb08bd0cb..4a053af8f4 100644 --- a/integration/testdata/spring4shell-jre11.json.golden +++ b/integration/testdata/spring4shell-jre11.json.golden @@ -26,6 +26,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:spring4shell-jre11" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:spring4shell-jre11", "ImageConfig": { "architecture": "amd64", "created": "2022-06-07T03:41:13.228952Z", diff --git a/integration/testdata/spring4shell-jre8.json.golden b/integration/testdata/spring4shell-jre8.json.golden index 5ff36f261f..e3ec0d4d44 100644 --- a/integration/testdata/spring4shell-jre8.json.golden +++ b/integration/testdata/spring4shell-jre8.json.golden @@ -26,6 +26,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:spring4shell-jre8" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:spring4shell-jre8", "ImageConfig": { "architecture": "amd64", "created": "2022-06-06T13:51:57.120019Z", diff --git a/integration/testdata/ubi-7-comprehensive.json.golden b/integration/testdata/ubi-7-comprehensive.json.golden index d86c5fb107..aa38483440 100644 --- a/integration/testdata/ubi-7-comprehensive.json.golden +++ b/integration/testdata/ubi-7-comprehensive.json.golden @@ -19,6 +19,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:ubi-7" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:ubi-7", "ImageConfig": { "architecture": "amd64", "created": "2019-09-02T12:56:43.939095Z", diff --git a/integration/testdata/ubi-7.json.golden b/integration/testdata/ubi-7.json.golden index b54ea11ace..a6cebcf177 100644 --- a/integration/testdata/ubi-7.json.golden +++ b/integration/testdata/ubi-7.json.golden @@ -19,6 +19,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:ubi-7" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:ubi-7", "ImageConfig": { "architecture": "amd64", "created": "2019-09-02T12:56:43.939095Z", diff --git a/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden b/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden index d8e4b670a0..784109a671 100644 --- a/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden +++ b/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden @@ -21,6 +21,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:ubuntu-1804" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:ubuntu-1804", "ImageConfig": { "architecture": "amd64", "container": "41b694b9b42f9c5ef7fb40c24272927a727a6d6cb8120bb3eae5849ceb9bee77", diff --git a/integration/testdata/ubuntu-1804.json.golden b/integration/testdata/ubuntu-1804.json.golden index dc4055a4ef..5aca90dd00 100644 --- a/integration/testdata/ubuntu-1804.json.golden +++ b/integration/testdata/ubuntu-1804.json.golden @@ -21,6 +21,7 @@ "RepoTags": [ "ghcr.io/aquasecurity/trivy-test-images:ubuntu-1804" ], + "Reference": "ghcr.io/aquasecurity/trivy-test-images:ubuntu-1804", "ImageConfig": { "architecture": "amd64", "container": "41b694b9b42f9c5ef7fb40c24272927a727a6d6cb8120bb3eae5849ceb9bee77", diff --git a/internal/testutil/image.go b/internal/testutil/image.go index 757d9770df..a9a233729d 100644 --- a/internal/testutil/image.go +++ b/internal/testutil/image.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/aquasecurity/trivy/pkg/fanal/image" + "github.com/aquasecurity/trivy/pkg/fanal/image/name" ) var ( @@ -72,9 +72,9 @@ func imageName(img, subpath, tag, digest string) string { } // MustParseReference parses a string into a Reference and fails the test if there's an error -func MustParseReference(t *testing.T, s string) image.Reference { +func MustParseReference(t *testing.T, s string) name.Reference { t.Helper() - ref, err := image.ParseReference(s) + ref, err := name.ParseReference(s) require.NoError(t, err) return ref } diff --git a/pkg/fanal/artifact/artifact.go b/pkg/fanal/artifact/artifact.go index 576a652ce8..4d9e4b3e00 100644 --- a/pkg/fanal/artifact/artifact.go +++ b/pkg/fanal/artifact/artifact.go @@ -8,7 +8,7 @@ import ( "github.com/google/go-containerregistry/pkg/v1" "github.com/aquasecurity/trivy/pkg/fanal/analyzer" - "github.com/aquasecurity/trivy/pkg/fanal/image" + "github.com/aquasecurity/trivy/pkg/fanal/image/name" "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/fanal/walker" "github.com/aquasecurity/trivy/pkg/misconf" @@ -104,7 +104,7 @@ type ImageMetadata struct { DiffIDs []string // uncompressed layer IDs RepoTags []string RepoDigests []string - Reference image.Reference // image reference matching the artifact name + Reference name.Reference // image reference matching the artifact name ConfigFile v1.ConfigFile } diff --git a/pkg/fanal/artifact/image/image.go b/pkg/fanal/artifact/image/image.go index 08c18d0e23..1f2a6e937c 100644 --- a/pkg/fanal/artifact/image/image.go +++ b/pkg/fanal/artifact/image/image.go @@ -1,7 +1,6 @@ package image import ( - "cmp" "context" "errors" "fmt" @@ -13,7 +12,6 @@ import ( "strings" "github.com/docker/go-units" - "github.com/google/go-containerregistry/pkg/name" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/samber/lo" "golang.org/x/sync/errgroup" @@ -24,6 +22,7 @@ import ( "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/fanal/handler" "github.com/aquasecurity/trivy/pkg/fanal/image" + "github.com/aquasecurity/trivy/pkg/fanal/image/name" "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/fanal/walker" "github.com/aquasecurity/trivy/pkg/log" @@ -173,48 +172,33 @@ func (a Artifact) Clean(_ artifact.Reference) error { } // findMatchingReference finds a RepoTag or RepoDigest that matches the artifact name -func (a Artifact) findMatchingReference(artifactName string, repoTags, repoDigests []string) image.Reference { +func (a Artifact) findMatchingReference(artifactName string, repoTags, repoDigests []string) name.Reference { // Convert strings to typed references - parsedTags := a.parseRepoTags(repoTags) - parsedDigests := a.parseRepoDigests(repoDigests) - - ref := a.findMatchingRepoReference(artifactName, parsedTags, parsedDigests) - return image.NewReference(ref) + references := a.parseImageReferences(slices.Concat(repoTags, repoDigests)) + return a.findMatchingRepoReference(artifactName, references) } -// parseRepoTags parses repo tags into name.Tag -func (a Artifact) parseRepoTags(repoTags []string) []name.Tag { - return lo.FilterMap(repoTags, func(tagStr string, _ int) (name.Tag, bool) { - tag, err := name.NewTag(tagStr) +// parseImageReferences parses repo tags/digests into name.Reference +func (a Artifact) parseImageReferences(references []string) []name.Reference { + return lo.FilterMap(references, func(ref string, _ int) (name.Reference, bool) { + tag, err := name.ParseReference(ref) if err != nil { - a.logger.Debug("Failed to parse repo tag", log.String("tag", tagStr), log.Err(err)) - return name.Tag{}, false + a.logger.Debug("Failed to parse repo tag/digest", log.String("ref", ref), log.Err(err)) + return name.Reference{}, false } return tag, true }) } -// parseRepoDigests parses repo digests into name.Digest -func (a Artifact) parseRepoDigests(repoDigests []string) []name.Digest { - return lo.FilterMap(repoDigests, func(digestStr string, _ int) (name.Digest, bool) { - digest, err := name.NewDigest(digestStr) - if err != nil { - a.logger.Debug("Failed to parse repo digest", log.String("digest", digestStr), log.Err(err)) - return name.Digest{}, false - } - return digest, true - }) -} - // findMatchingRepoReference finds a RepoTag or RepoDigest that matches the artifact name -func (a Artifact) findMatchingRepoReference(artifactName string, repoTags []name.Tag, repoDigests []name.Digest) name.Reference { +func (a Artifact) findMatchingRepoReference(artifactName string, references []name.Reference) name.Reference { // If there are no RepoTags or RepoDigests, return nil - if len(repoTags) == 0 && len(repoDigests) == 0 { - return nil + if len(references) == 0 { + return name.Reference{} } - // Select the first available reference as fallback - fallback := cmp.Or[name.Reference](lo.FirstOrEmpty(repoTags), lo.FirstOrEmpty(repoDigests)) + // Use the first available reference as fallback (tags take precedence over digests) + fallback := lo.FirstOrEmpty(references) // TODO(knqyf263): refactor to use a more robust method instead of suffix-based detection // Check if artifact name looks like a file path (tar archive) @@ -240,22 +224,11 @@ func (a Artifact) findMatchingRepoReference(artifactName string, repoTags []name } artifactRefName := artifactRef.Name() - - switch artifactRef.(type) { - case name.Digest: - // Try to find a matching digest from RepoDigests - if digest, ok := lo.Find(repoDigests, func(d name.Digest) bool { - return artifactRefName == d.Name() - }); ok { - return digest - } - case name.Tag: - // Try to find a matching tag from RepoTags - if tag, ok := lo.Find(repoTags, func(t name.Tag) bool { - return artifactRefName == t.Name() - }); ok { - return tag - } + // Try to find a matching digest from RepoTags/RepoDigests + if ref, ok := lo.Find(references, func(d name.Reference) bool { + return artifactRefName == d.Name() + }); ok { + return ref } // If no matching tag/digest found, use the first RepoTag or RepoDigest as fallback diff --git a/pkg/fanal/artifact/sbom/sbom.go b/pkg/fanal/artifact/sbom/sbom.go index 3a0f4aa454..a09cbd2125 100644 --- a/pkg/fanal/artifact/sbom/sbom.go +++ b/pkg/fanal/artifact/sbom/sbom.go @@ -94,6 +94,7 @@ func (a Artifact) Inspect(ctx context.Context) (artifact.Reference, error) { DiffIDs: bom.Metadata.DiffIDs, RepoTags: bom.Metadata.RepoTags, RepoDigests: bom.Metadata.RepoDigests, + Reference: bom.Metadata.Reference, }, // Keep an original report diff --git a/pkg/fanal/artifact/sbom/sbom_test.go b/pkg/fanal/artifact/sbom/sbom_test.go index abfefee229..9b1c3c6468 100644 --- a/pkg/fanal/artifact/sbom/sbom_test.go +++ b/pkg/fanal/artifact/sbom/sbom_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/aquasecurity/trivy/internal/cachetest" + "github.com/aquasecurity/trivy/internal/testutil" "github.com/aquasecurity/trivy/pkg/cache" "github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/fanal/artifact/sbom" @@ -203,6 +204,7 @@ func TestArtifact_Inspect(t *testing.T) { RepoTags: []string{ "maven-test-project:latest", }, + Reference: testutil.MustParseReference(t, "maven-test-project:latest"), }, }, }, diff --git a/pkg/fanal/artifact/sbom/testdata/bom.json b/pkg/fanal/artifact/sbom/testdata/bom.json index f8fd55ea6a..b5645eca53 100644 --- a/pkg/fanal/artifact/sbom/testdata/bom.json +++ b/pkg/fanal/artifact/sbom/testdata/bom.json @@ -39,6 +39,10 @@ { "name": "aquasecurity:trivy:RepoTag", "value": "maven-test-project:latest" + }, + { + "name": "aquasecurity:trivy:Reference", + "value": "maven-test-project:latest" } ] } diff --git a/pkg/fanal/image/reference.go b/pkg/fanal/image/name/reference.go similarity index 83% rename from pkg/fanal/image/reference.go rename to pkg/fanal/image/name/reference.go index fea0e55717..102a7ee208 100644 --- a/pkg/fanal/image/reference.go +++ b/pkg/fanal/image/name/reference.go @@ -1,4 +1,4 @@ -package image +package name import ( "encoding/json" @@ -13,11 +13,6 @@ type Reference struct { name.Reference } -// NewReference creates a new Reference from name.Reference -func NewReference(ref name.Reference) Reference { - return Reference{Reference: ref} -} - // ParseReference parses a string into a Reference func ParseReference(s string) (Reference, error) { if s == "" { @@ -56,7 +51,7 @@ func (r *Reference) UnmarshalJSON(data []byte) error { return nil } -// IsEmpty returns true if the reference is empty -func (r Reference) IsEmpty() bool { +// IsZero returns true if the reference is empty (for omitzero support) +func (r Reference) IsZero() bool { return lo.IsNil(r.Reference) } diff --git a/pkg/fanal/image/reference_test.go b/pkg/fanal/image/name/reference_test.go similarity index 92% rename from pkg/fanal/image/reference_test.go rename to pkg/fanal/image/name/reference_test.go index fca571bc39..1d1da96c08 100644 --- a/pkg/fanal/image/reference_test.go +++ b/pkg/fanal/image/name/reference_test.go @@ -1,4 +1,4 @@ -package image_test +package name_test import ( "encoding/json" @@ -8,13 +8,13 @@ import ( "github.com/stretchr/testify/require" "github.com/aquasecurity/trivy/internal/testutil" - "github.com/aquasecurity/trivy/pkg/fanal/image" + "github.com/aquasecurity/trivy/pkg/fanal/image/name" ) func TestReference_MarshalJSON(t *testing.T) { tests := []struct { name string - ref image.Reference + ref name.Reference want string }{ { @@ -29,7 +29,7 @@ func TestReference_MarshalJSON(t *testing.T) { }, { name: "empty reference", - ref: image.Reference{}, + ref: name.Reference{}, want: `""`, }, } @@ -81,14 +81,14 @@ func TestReference_UnmarshalJSON(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - var r image.Reference + var r name.Reference err := json.Unmarshal([]byte(tt.json), &r) tt.wantErr(t, err) if err != nil { return } - assert.Equal(t, tt.wantIsEmpty, r.IsEmpty()) - if !r.IsEmpty() { + assert.Equal(t, tt.wantIsEmpty, r.IsZero()) + if !r.IsZero() { assert.Equal(t, tt.want, r.String()) } }) @@ -98,7 +98,7 @@ func TestReference_UnmarshalJSON(t *testing.T) { func TestReference_String(t *testing.T) { tests := []struct { name string - ref image.Reference + ref name.Reference want string }{ { @@ -128,7 +128,7 @@ func TestReference_String(t *testing.T) { func TestReference_Context(t *testing.T) { tests := []struct { name string - ref image.Reference + ref name.Reference want string }{ { @@ -158,7 +158,7 @@ func TestReference_Context(t *testing.T) { func TestReference_IsEmpty(t *testing.T) { tests := []struct { name string - ref image.Reference + ref name.Reference want bool }{ { @@ -168,14 +168,14 @@ func TestReference_IsEmpty(t *testing.T) { }, { name: "empty reference", - ref: image.Reference{}, + ref: name.Reference{}, want: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, tt.ref.IsEmpty()) + assert.Equal(t, tt.want, tt.ref.IsZero()) }) } } @@ -188,7 +188,7 @@ func TestReference_JSONRoundTrip(t *testing.T) { require.NoError(t, err) // Unmarshal from JSON - var decoded image.Reference + var decoded name.Reference err = json.Unmarshal(data, &decoded) require.NoError(t, err) diff --git a/pkg/sbom/core/bom.go b/pkg/sbom/core/bom.go index 6f22f7d852..6003dfddd0 100644 --- a/pkg/sbom/core/bom.go +++ b/pkg/sbom/core/bom.go @@ -33,6 +33,7 @@ const ( PropertyRepoDigest = "RepoDigest" PropertyDiffID = "DiffID" PropertyRepoTag = "RepoTag" + PropertyReference = "Reference" PropertyLabelsPrefix = "Labels" // Package properties diff --git a/pkg/sbom/io/decode.go b/pkg/sbom/io/decode.go index 3ca27088a2..7265c18b65 100644 --- a/pkg/sbom/io/decode.go +++ b/pkg/sbom/io/decode.go @@ -15,6 +15,7 @@ import ( "golang.org/x/xerrors" "github.com/aquasecurity/trivy/pkg/dependency" + "github.com/aquasecurity/trivy/pkg/fanal/image/name" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/purl" @@ -105,6 +106,10 @@ func (m *Decoder) decodeRoot(s *types.SBOM) error { s.Metadata.DiffIDs = append(s.Metadata.DiffIDs, prop.Value) case core.PropertyRepoTag: s.Metadata.RepoTags = append(s.Metadata.RepoTags, prop.Value) + case core.PropertyReference: + if s.Metadata.Reference, err = name.ParseReference(prop.Value); err != nil { + m.logger.Warn("Failed to parse image reference", log.String("value", prop.Value), log.Err(err)) + } } } return nil diff --git a/pkg/sbom/io/encode.go b/pkg/sbom/io/encode.go index b691ee3a35..a26cd2fbd8 100644 --- a/pkg/sbom/io/encode.go +++ b/pkg/sbom/io/encode.go @@ -167,6 +167,13 @@ func (e *Encoder) rootComponent(r types.Report) (*core.Component, error) { }) } + if !r.Metadata.Reference.IsZero() { + props = append(props, core.Property{ + Name: core.PropertyReference, + Value: r.Metadata.Reference.String(), + }) + } + root.Properties = filterProperties(props) return root, nil diff --git a/pkg/scan/service.go b/pkg/scan/service.go index af6f8b3f1b..b92ea497ba 100644 --- a/pkg/scan/service.go +++ b/pkg/scan/service.go @@ -92,6 +92,7 @@ func (s Service) ScanArtifact(ctx context.Context, options types.ScanOptions) (t DiffIDs: artifactInfo.ImageMetadata.DiffIDs, RepoTags: artifactInfo.ImageMetadata.RepoTags, RepoDigests: artifactInfo.ImageMetadata.RepoDigests, + Reference: artifactInfo.ImageMetadata.Reference, ImageConfig: artifactInfo.ImageMetadata.ConfigFile, Size: scanResponse.Layers.TotalSize(), Layers: lo.Ternary(len(scanResponse.Layers) > 0, scanResponse.Layers, nil), @@ -125,7 +126,7 @@ func (s Service) generateArtifactID(artifactInfo artifact.Reference) string { // Use the Reference field if available ref := artifactInfo.ImageMetadata.Reference - if ref.IsEmpty() { + if ref.IsZero() { // Reference is empty when RepoTags and RepoDigests are both empty. // This happens in the following cases: // 1. Images built without tags (e.g., "docker build ." without -t flag) diff --git a/pkg/scan/service_test.go b/pkg/scan/service_test.go index e1e7d7e649..a73d72e046 100644 --- a/pkg/scan/service_test.go +++ b/pkg/scan/service_test.go @@ -12,6 +12,7 @@ import ( "github.com/aquasecurity/trivy-db/pkg/db" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy/internal/dbtest" + "github.com/aquasecurity/trivy/internal/testutil" "github.com/aquasecurity/trivy/pkg/cache" "github.com/aquasecurity/trivy/pkg/clock" "github.com/aquasecurity/trivy/pkg/fanal/applier" @@ -77,6 +78,7 @@ func TestScanner_ScanArtifact(t *testing.T) { DiffID: "sha256:beee9f30bc1f711043e78d4a2be0668955d4b761d587d6f60c2c8dc081efb203", }, }, + Reference: testutil.MustParseReference(t, "alpine:3.11"), ImageConfig: v1.ConfigFile{ Architecture: "amd64", Container: "fb71ddde5f6411a82eb056a9190f0cc1c80d7f77a8509ee90a2054428edb0024", diff --git a/pkg/types/report.go b/pkg/types/report.go index 1d63eac6a8..c211879361 100644 --- a/pkg/types/report.go +++ b/pkg/types/report.go @@ -5,6 +5,7 @@ import ( v1 "github.com/google/go-containerregistry/pkg/v1" // nolint: goimports + "github.com/aquasecurity/trivy/pkg/fanal/image/name" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/sbom/core" ) @@ -37,12 +38,13 @@ type Metadata struct { OS *ftypes.OS `json:",omitempty"` // Container image - ImageID string `json:",omitempty"` - DiffIDs []string `json:",omitempty"` - RepoTags []string `json:",omitempty"` - RepoDigests []string `json:",omitempty"` - ImageConfig v1.ConfigFile `json:",omitzero"` - Layers ftypes.Layers `json:",omitzero"` + ImageID string `json:",omitempty"` + DiffIDs []string `json:",omitempty"` + RepoTags []string `json:",omitempty"` + RepoDigests []string `json:",omitempty"` + Reference name.Reference `json:",omitzero"` + ImageConfig v1.ConfigFile `json:",omitzero"` + Layers ftypes.Layers `json:",omitzero"` // Git repository RepoURL string `json:",omitzero"`