mirror of
https://github.com/anchore/syft.git
synced 2026-02-12 02:26:42 +01:00
feat: update spdx format model to produce valid spdx json documents (#1418)
This commit is contained in:
parent
5dd726fc86
commit
3690f979b3
@ -8,6 +8,11 @@ const (
|
||||
// Example: The package 'WildFly' is described by SPDX document WildFly.spdx.
|
||||
DescribedByRelationship RelationshipType = "DESCRIBED_BY"
|
||||
|
||||
// Describes is to be used when SPDXRef-DOCUMENT describes SPDXRef-A.
|
||||
// Example: An SPDX document WildFly.spdx describes package ‘WildFly’.
|
||||
// Note this is a logical relationship to help organize related items within an SPDX document that is mandatory if more than one package or set of files (not in a package) is present.
|
||||
DescribesRelationship RelationshipType = "DESCRIBES"
|
||||
|
||||
// ContainsRelationship is to be used when SPDXRef-A contains SPDXRef-B.
|
||||
// Example: An ARCHIVE file bar.tgz contains a SOURCE file foo.c.
|
||||
ContainsRelationship RelationshipType = "CONTAINS"
|
||||
|
||||
@ -33,6 +33,24 @@ const (
|
||||
//nolint:funlen
|
||||
func ToFormatModel(s sbom.SBOM) *spdx.Document {
|
||||
name, namespace := DocumentNameAndNamespace(s.Source)
|
||||
relationships := toRelationships(s.RelationshipsSorted())
|
||||
|
||||
// for valid SPDX we need a document describes relationship
|
||||
// TODO: remove this placeholder after deciding on correct behavior
|
||||
// for the primary package purpose field:
|
||||
// https://spdx.github.io/spdx-spec/v2.3/package-information/#724-primary-package-purpose-field
|
||||
documentDescribesRelationship := &spdx.Relationship{
|
||||
RefA: common.DocElementID{
|
||||
ElementRefID: "DOCUMENT",
|
||||
},
|
||||
Relationship: string(DescribesRelationship),
|
||||
RefB: common.DocElementID{
|
||||
ElementRefID: "DOCUMENT",
|
||||
},
|
||||
RelationshipComment: "",
|
||||
}
|
||||
|
||||
relationships = append(relationships, documentDescribesRelationship)
|
||||
|
||||
return &spdx.Document{
|
||||
// 6.1: SPDX Version; should be in the format "SPDX-x.x"
|
||||
@ -107,7 +125,7 @@ func ToFormatModel(s sbom.SBOM) *spdx.Document {
|
||||
},
|
||||
Packages: toPackages(s.Artifacts.PackageCatalog, s),
|
||||
Files: toFiles(s),
|
||||
Relationships: toRelationships(s.RelationshipsSorted()),
|
||||
Relationships: relationships,
|
||||
}
|
||||
}
|
||||
|
||||
@ -407,6 +425,15 @@ func toFiles(s sbom.SBOM) (results []*spdx.File) {
|
||||
digests = digestsForLocation
|
||||
}
|
||||
|
||||
// if we don't have any metadata or digests for this location
|
||||
// then the file is most likely a symlink or non-regular file
|
||||
// for now we include a 0 sha1 digest as requested by the spdx spec
|
||||
// TODO: update location code in core SBOM so that we can map complex links
|
||||
// back to their real file digest location.
|
||||
if len(digests) == 0 {
|
||||
digests = append(digests, file.Digest{Algorithm: "sha1", Value: "0000000000000000000000000000000000000000"})
|
||||
}
|
||||
|
||||
// TODO: add file classifications (?) and content as a snippet
|
||||
|
||||
var comment string
|
||||
|
||||
@ -3,14 +3,14 @@
|
||||
"dataLicense": "CC0-1.0",
|
||||
"SPDXID": "SPDXRef-DOCUMENT",
|
||||
"name": "/some/path",
|
||||
"documentNamespace": "https://anchore.com/syft/dir/some/path-4bf54cdd-0a0f-4560-bf4f-39cac2ef7a5b",
|
||||
"documentNamespace": "https://anchore.com/syft/dir/some/path-116e86ba-a976-48ed-909d-9278807ee7fe",
|
||||
"creationInfo": {
|
||||
"licenseListVersion": "3.18",
|
||||
"licenseListVersion": "3.19",
|
||||
"creators": [
|
||||
"Organization: Anchore, Inc",
|
||||
"Tool: syft-v0.42.0-bogus"
|
||||
],
|
||||
"created": "2022-11-19T13:46:57Z",
|
||||
"created": "2022-12-21T03:39:05Z",
|
||||
"comment": ""
|
||||
},
|
||||
"packages": [
|
||||
@ -62,5 +62,12 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"relationships": [
|
||||
{
|
||||
"spdxElementId": "SPDXRef-DOCUMENT",
|
||||
"relatedSpdxElement": "SPDXRef-DOCUMENT",
|
||||
"relationshipType": "DESCRIBES"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -3,14 +3,14 @@
|
||||
"dataLicense": "CC0-1.0",
|
||||
"SPDXID": "SPDXRef-DOCUMENT",
|
||||
"name": "user-image-input",
|
||||
"documentNamespace": "https://anchore.com/syft/image/user-image-input-102ca7dc-3d1e-46d2-b130-28968831ebcc",
|
||||
"documentNamespace": "https://anchore.com/syft/image/user-image-input-006b9b96-66f1-4de3-897f-6583b4358c87",
|
||||
"creationInfo": {
|
||||
"licenseListVersion": "3.18",
|
||||
"licenseListVersion": "3.19",
|
||||
"creators": [
|
||||
"Organization: Anchore, Inc",
|
||||
"Tool: syft-v0.42.0-bogus"
|
||||
],
|
||||
"created": "2022-11-19T13:46:57Z",
|
||||
"created": "2022-12-21T03:39:05Z",
|
||||
"comment": ""
|
||||
},
|
||||
"packages": [
|
||||
@ -62,5 +62,12 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"relationships": [
|
||||
{
|
||||
"spdxElementId": "SPDXRef-DOCUMENT",
|
||||
"relatedSpdxElement": "SPDXRef-DOCUMENT",
|
||||
"relationshipType": "DESCRIBES"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -3,14 +3,14 @@
|
||||
"dataLicense": "CC0-1.0",
|
||||
"SPDXID": "SPDXRef-DOCUMENT",
|
||||
"name": "user-image-input",
|
||||
"documentNamespace": "https://anchore.com/syft/image/user-image-input-ace88a38-4633-4bff-8fa3-8ae929dab37d",
|
||||
"documentNamespace": "https://anchore.com/syft/image/user-image-input-552a9cfc-49ee-4706-81cb-723fd7146b4f",
|
||||
"creationInfo": {
|
||||
"licenseListVersion": "3.19",
|
||||
"creators": [
|
||||
"Organization: Anchore, Inc",
|
||||
"Tool: syft-v0.42.0-bogus"
|
||||
],
|
||||
"created": "2022-12-14T18:21:40Z",
|
||||
"created": "2022-12-21T03:39:05Z",
|
||||
"comment": ""
|
||||
},
|
||||
"packages": [
|
||||
@ -70,7 +70,12 @@
|
||||
"fileTypes": [
|
||||
"OTHER"
|
||||
],
|
||||
"checksums": [],
|
||||
"checksums": [
|
||||
{
|
||||
"algorithm": "SHA1",
|
||||
"checksumValue": "0000000000000000000000000000000000000000"
|
||||
}
|
||||
],
|
||||
"licenseConcluded": "NOASSERTION",
|
||||
"copyrightText": ""
|
||||
},
|
||||
@ -80,7 +85,12 @@
|
||||
"fileTypes": [
|
||||
"OTHER"
|
||||
],
|
||||
"checksums": [],
|
||||
"checksums": [
|
||||
{
|
||||
"algorithm": "SHA1",
|
||||
"checksumValue": "0000000000000000000000000000000000000000"
|
||||
}
|
||||
],
|
||||
"licenseConcluded": "NOASSERTION",
|
||||
"copyrightText": ""
|
||||
},
|
||||
@ -90,7 +100,12 @@
|
||||
"fileTypes": [
|
||||
"OTHER"
|
||||
],
|
||||
"checksums": [],
|
||||
"checksums": [
|
||||
{
|
||||
"algorithm": "SHA1",
|
||||
"checksumValue": "0000000000000000000000000000000000000000"
|
||||
}
|
||||
],
|
||||
"licenseConcluded": "NOASSERTION",
|
||||
"copyrightText": ""
|
||||
},
|
||||
@ -100,7 +115,12 @@
|
||||
"fileTypes": [
|
||||
"OTHER"
|
||||
],
|
||||
"checksums": [],
|
||||
"checksums": [
|
||||
{
|
||||
"algorithm": "SHA1",
|
||||
"checksumValue": "0000000000000000000000000000000000000000"
|
||||
}
|
||||
],
|
||||
"licenseConcluded": "NOASSERTION",
|
||||
"copyrightText": ""
|
||||
},
|
||||
@ -110,7 +130,12 @@
|
||||
"fileTypes": [
|
||||
"OTHER"
|
||||
],
|
||||
"checksums": [],
|
||||
"checksums": [
|
||||
{
|
||||
"algorithm": "SHA1",
|
||||
"checksumValue": "0000000000000000000000000000000000000000"
|
||||
}
|
||||
],
|
||||
"licenseConcluded": "NOASSERTION",
|
||||
"copyrightText": ""
|
||||
},
|
||||
@ -120,7 +145,12 @@
|
||||
"fileTypes": [
|
||||
"OTHER"
|
||||
],
|
||||
"checksums": [],
|
||||
"checksums": [
|
||||
{
|
||||
"algorithm": "SHA1",
|
||||
"checksumValue": "0000000000000000000000000000000000000000"
|
||||
}
|
||||
],
|
||||
"licenseConcluded": "NOASSERTION",
|
||||
"copyrightText": ""
|
||||
}
|
||||
@ -155,6 +185,11 @@
|
||||
"spdxElementId": "SPDXRef-Package-python-package-1-66ba429119b8bec6",
|
||||
"relatedSpdxElement": "SPDXRef-f9e49132a4b96ccd",
|
||||
"relationshipType": "CONTAINS"
|
||||
},
|
||||
{
|
||||
"spdxElementId": "SPDXRef-DOCUMENT",
|
||||
"relatedSpdxElement": "SPDXRef-DOCUMENT",
|
||||
"relationshipType": "DESCRIBES"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Binary file not shown.
@ -2,11 +2,11 @@ SPDXVersion: SPDX-2.3
|
||||
DataLicense: CC0-1.0
|
||||
SPDXID: SPDXRef-DOCUMENT
|
||||
DocumentName: foobar/baz
|
||||
DocumentNamespace: https://anchore.com/syft/dir/foobar/baz-62bc0aae-2b37-4c86-ab79-63c6fc4198ed
|
||||
LicenseListVersion: 3.18
|
||||
DocumentNamespace: https://anchore.com/syft/dir/foobar/baz-478e410d-7fad-472c-b4e9-a4068ef28160
|
||||
LicenseListVersion: 3.19
|
||||
Creator: Organization: Anchore, Inc
|
||||
Creator: Tool: syft-v0.42.0-bogus
|
||||
Created: 2022-11-19T13:48:30Z
|
||||
Created: 2022-12-21T03:39:05Z
|
||||
|
||||
##### Package: @at-sign
|
||||
|
||||
@ -41,3 +41,7 @@ PackageLicenseConcluded: NONE
|
||||
PackageLicenseDeclared: NONE
|
||||
PackageCopyrightText: NOASSERTION
|
||||
|
||||
##### Relationships
|
||||
|
||||
Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-DOCUMENT
|
||||
|
||||
|
||||
@ -2,42 +2,48 @@ SPDXVersion: SPDX-2.3
|
||||
DataLicense: CC0-1.0
|
||||
SPDXID: SPDXRef-DOCUMENT
|
||||
DocumentName: user-image-input
|
||||
DocumentNamespace: https://anchore.com/syft/image/user-image-input-cc20e416-9c74-401c-b4aa-245556bada5e
|
||||
LicenseListVersion: 3.18
|
||||
DocumentNamespace: https://anchore.com/syft/image/user-image-input-73433e8c-364f-42b6-b5b7-9a4da8799868
|
||||
LicenseListVersion: 3.19
|
||||
Creator: Organization: Anchore, Inc
|
||||
Creator: Tool: syft-v0.42.0-bogus
|
||||
Created: 2022-11-19T13:48:30Z
|
||||
Created: 2022-12-21T03:39:05Z
|
||||
|
||||
##### Unpackaged files
|
||||
|
||||
FileName: /f1
|
||||
SPDXID: SPDXRef-5265a4dde3edbf7c
|
||||
FileType: OTHER
|
||||
FileChecksum: SHA1: 0000000000000000000000000000000000000000
|
||||
LicenseConcluded: NOASSERTION
|
||||
|
||||
FileName: /z1/f5
|
||||
SPDXID: SPDXRef-839d99ee67d9d174
|
||||
FileType: OTHER
|
||||
FileChecksum: SHA1: 0000000000000000000000000000000000000000
|
||||
LicenseConcluded: NOASSERTION
|
||||
|
||||
FileName: /a1/f6
|
||||
SPDXID: SPDXRef-9c2f7510199b17f6
|
||||
FileType: OTHER
|
||||
FileChecksum: SHA1: 0000000000000000000000000000000000000000
|
||||
LicenseConcluded: NOASSERTION
|
||||
|
||||
FileName: /d2/f4
|
||||
SPDXID: SPDXRef-c641caa71518099f
|
||||
FileType: OTHER
|
||||
FileChecksum: SHA1: 0000000000000000000000000000000000000000
|
||||
LicenseConcluded: NOASSERTION
|
||||
|
||||
FileName: /d1/f3
|
||||
SPDXID: SPDXRef-c6f5b29dca12661f
|
||||
FileType: OTHER
|
||||
FileChecksum: SHA1: 0000000000000000000000000000000000000000
|
||||
LicenseConcluded: NOASSERTION
|
||||
|
||||
FileName: /f2
|
||||
SPDXID: SPDXRef-f9e49132a4b96ccd
|
||||
FileType: OTHER
|
||||
FileChecksum: SHA1: 0000000000000000000000000000000000000000
|
||||
LicenseConcluded: NOASSERTION
|
||||
|
||||
##### Package: package-2
|
||||
@ -76,4 +82,5 @@ Relationship: SPDXRef-Package-python-package-1-66ba429119b8bec6 CONTAINS SPDXRef
|
||||
Relationship: SPDXRef-Package-python-package-1-66ba429119b8bec6 CONTAINS SPDXRef-c641caa71518099f
|
||||
Relationship: SPDXRef-Package-python-package-1-66ba429119b8bec6 CONTAINS SPDXRef-c6f5b29dca12661f
|
||||
Relationship: SPDXRef-Package-python-package-1-66ba429119b8bec6 CONTAINS SPDXRef-f9e49132a4b96ccd
|
||||
Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-DOCUMENT
|
||||
|
||||
|
||||
@ -2,11 +2,11 @@ SPDXVersion: SPDX-2.3
|
||||
DataLicense: CC0-1.0
|
||||
SPDXID: SPDXRef-DOCUMENT
|
||||
DocumentName: /some/path
|
||||
DocumentNamespace: https://anchore.com/syft/dir/some/path-7a4b2140-6669-4a28-80dd-5c8e795c5da0
|
||||
LicenseListVersion: 3.18
|
||||
DocumentNamespace: https://anchore.com/syft/dir/some/path-1d303762-46d2-47b5-9c81-defa91387275
|
||||
LicenseListVersion: 3.19
|
||||
Creator: Organization: Anchore, Inc
|
||||
Creator: Tool: syft-v0.42.0-bogus
|
||||
Created: 2022-11-19T13:48:30Z
|
||||
Created: 2022-12-21T03:39:05Z
|
||||
|
||||
##### Package: package-2
|
||||
|
||||
@ -36,3 +36,7 @@ PackageCopyrightText: NOASSERTION
|
||||
ExternalRef: SECURITY cpe23Type cpe:2.3:*:some:package:2:*:*:*:*:*:*:*
|
||||
ExternalRef: PACKAGE-MANAGER purl a-purl-2
|
||||
|
||||
##### Relationships
|
||||
|
||||
Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-DOCUMENT
|
||||
|
||||
|
||||
@ -2,11 +2,11 @@ SPDXVersion: SPDX-2.3
|
||||
DataLicense: CC0-1.0
|
||||
SPDXID: SPDXRef-DOCUMENT
|
||||
DocumentName: user-image-input
|
||||
DocumentNamespace: https://anchore.com/syft/image/user-image-input-baff7ada-85cb-403e-90d7-05b0c6d79490
|
||||
LicenseListVersion: 3.18
|
||||
DocumentNamespace: https://anchore.com/syft/image/user-image-input-559af225-63af-4bc0-94fb-bce94913bcfa
|
||||
LicenseListVersion: 3.19
|
||||
Creator: Organization: Anchore, Inc
|
||||
Creator: Tool: syft-v0.42.0-bogus
|
||||
Created: 2022-11-19T13:48:30Z
|
||||
Created: 2022-12-21T03:39:05Z
|
||||
|
||||
##### Package: package-2
|
||||
|
||||
@ -36,3 +36,7 @@ PackageCopyrightText: NOASSERTION
|
||||
ExternalRef: SECURITY cpe23Type cpe:2.3:*:some:package:1:*:*:*:*:*:*:*
|
||||
ExternalRef: PACKAGE-MANAGER purl a-purl-1
|
||||
|
||||
##### Relationships
|
||||
|
||||
Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-DOCUMENT
|
||||
|
||||
|
||||
Binary file not shown.
@ -6,6 +6,7 @@ import (
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -26,6 +27,29 @@ func TestSpdxValidationTooling(t *testing.T) {
|
||||
images: []string{"alpine:latest", "photon:3.0", "debian:latest"},
|
||||
env: map[string]string{
|
||||
"SYFT_FILE_METADATA_CATALOGER_ENABLED": "true",
|
||||
"SYFT_FILE_CONTENTS_CATALOGER_ENABLED": "true",
|
||||
"SYFT_FILE_METADATA_DIGESTS": "sha1",
|
||||
},
|
||||
setup: func(t *testing.T) {
|
||||
cwd, err := os.Getwd()
|
||||
require.NoError(t, err)
|
||||
fixturesPath := filepath.Join(cwd, "test-fixtures", "image-java-spdx-tools")
|
||||
buildCmd := exec.Command("make", "build")
|
||||
buildCmd.Dir = fixturesPath
|
||||
err = buildCmd.Run()
|
||||
require.NoError(t, err)
|
||||
},
|
||||
assertions: []traitAssertion{
|
||||
assertSuccessfulReturnCode,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "spdx validation tooling json",
|
||||
syftArgs: []string{"packages", "-o", "spdx-json"},
|
||||
images: []string{"alpine:latest", "photon:3.0", "debian:latest"},
|
||||
env: map[string]string{
|
||||
"SYFT_FILE_METADATA_CATALOGER_ENABLED": "true",
|
||||
"SYFT_FILE_CONTENTS_CATALOGER_ENABLED": "true",
|
||||
"SYFT_FILE_METADATA_DIGESTS": "sha1",
|
||||
},
|
||||
setup: func(t *testing.T) {
|
||||
@ -61,8 +85,15 @@ func TestSpdxValidationTooling(t *testing.T) {
|
||||
f, err := os.CreateTemp(t.TempDir(), "temp")
|
||||
require.NoError(t, err)
|
||||
|
||||
var suffix string
|
||||
if strings.Contains(test.name, "json") {
|
||||
suffix = ".json"
|
||||
} else {
|
||||
suffix = ".spdx"
|
||||
}
|
||||
|
||||
// spdx tooling only takes a file with suffix spdx
|
||||
rename := path.Join(path.Dir(f.Name()), fmt.Sprintf("%s.spdx", path.Base(f.Name())))
|
||||
rename := path.Join(path.Dir(f.Name()), fmt.Sprintf("%s.%s", path.Base(f.Name()), suffix))
|
||||
err = os.Rename(f.Name(), rename)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user