Update cyclonedx to v1.4 (#820)

This commit is contained in:
Sambhav Kothari
2022-03-08 12:09:55 -05:00
committed by GitHub
parent f2617285d0
commit 39737a2825
31 changed files with 5002 additions and 3453 deletions
@@ -0,0 +1,70 @@
package cyclonedxjson
import (
"fmt"
"os"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func Test_decodeJSON(t *testing.T) {
tests := []struct {
file string
err bool
distro string
packages []string
}{
{
file: "snapshot/TestCycloneDxDirectoryEncoder.golden",
distro: "debian:1.2.3",
packages: []string{"package-1:1.0.1", "package-2:2.0.1"},
},
{
file: "snapshot/TestCycloneDxImageEncoder.golden",
distro: "debian:1.2.3",
packages: []string{"package-1:1.0.1", "package-2:2.0.1"},
},
{
file: "image-simple/Dockerfile",
err: true,
},
}
for _, test := range tests {
t.Run(test.file, func(t *testing.T) {
reader, err := os.Open("test-fixtures/" + test.file)
assert.NoError(t, err)
if test.err {
err = Format().Validate(reader)
assert.Error(t, err)
return
}
bom, err := Format().Decode(reader)
assert.NoError(t, err)
split := strings.SplitN(test.distro, ":", 2)
name := split[0]
version := split[1]
assert.Equal(t, bom.Artifacts.LinuxDistribution.ID, name)
assert.Equal(t, bom.Artifacts.LinuxDistribution.Version, version)
pkgs:
for _, pkg := range test.packages {
split = strings.SplitN(pkg, ":", 2)
name = split[0]
version = split[1]
for p := range bom.Artifacts.PackageCatalog.Enumerate() {
if p.Name == name {
assert.Equal(t, version, p.Version)
continue pkgs
}
}
assert.Fail(t, fmt.Sprintf("package should be present: %s", pkg))
}
})
}
}
+18
View File
@@ -0,0 +1,18 @@
package cyclonedxjson
import (
"io"
"github.com/CycloneDX/cyclonedx-go"
"github.com/anchore/syft/internal/formats/common/cyclonedxhelpers"
"github.com/anchore/syft/syft/sbom"
)
func encoder(output io.Writer, s sbom.SBOM) error {
bom := cyclonedxhelpers.ToFormatModel(s)
enc := cyclonedx.NewBOMEncoder(output, cyclonedx.BOMFileFormatJSON)
enc.SetPretty(true)
err := enc.Encode(bom)
return err
}
@@ -0,0 +1,44 @@
package cyclonedxjson
import (
"flag"
"regexp"
"testing"
"github.com/anchore/syft/internal/formats/common/testutils"
)
var updateCycloneDx = flag.Bool("update-cyclonedx", false, "update the *.golden files for cyclone-dx encoders")
func TestCycloneDxDirectoryEncoder(t *testing.T) {
testutils.AssertEncoderAgainstGoldenSnapshot(t,
Format(),
testutils.DirectoryInput(t),
*updateCycloneDx,
cycloneDxRedactor,
)
}
func TestCycloneDxImageEncoder(t *testing.T) {
testImage := "image-simple"
testutils.AssertEncoderAgainstGoldenImageSnapshot(t,
Format(),
testutils.ImageInput(t, testImage),
testImage,
*updateCycloneDx,
cycloneDxRedactor,
)
}
func cycloneDxRedactor(s []byte) []byte {
serialPattern := regexp.MustCompile(`urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`)
rfc3339Pattern := regexp.MustCompile(`([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([Zz])|([\+|\-]([01][0-9]|2[0-3]):[0-5][0-9]))`)
sha256Pattern := regexp.MustCompile(`sha256:[A-Fa-f0-9]{64}`)
for _, pattern := range []*regexp.Regexp{serialPattern, rfc3339Pattern, sha256Pattern} {
s = pattern.ReplaceAll(s, []byte("redacted"))
}
// the bom-ref will be autogenerated every time, the value here should not be directly tested in snapshot tests
s = regexp.MustCompile(` "bom-ref": .*\n`).ReplaceAll(s, []byte(""))
return s
}
+18
View File
@@ -0,0 +1,18 @@
package cyclonedxjson
import (
"github.com/CycloneDX/cyclonedx-go"
"github.com/anchore/syft/internal/formats/common/cyclonedxhelpers"
"github.com/anchore/syft/syft/sbom"
)
const ID sbom.FormatID = "cyclonedx-1-json"
func Format() sbom.Format {
return sbom.NewFormat(
ID,
encoder,
cyclonedxhelpers.GetDecoder(cyclonedx.BOMFileFormatJSON),
cyclonedxhelpers.GetValidator(cyclonedx.BOMFileFormatJSON),
)
}
@@ -0,0 +1,4 @@
# Note: changes to this file will result in updating several test values. Consider making a new image fixture instead of editing this one.
FROM scratch
ADD file-1.txt /somefile-1.txt
ADD file-2.txt /somefile-2.txt
@@ -0,0 +1 @@
this file has contents
@@ -0,0 +1 @@
file-2 contents!
@@ -0,0 +1,117 @@
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"serialNumber": "urn:uuid:498e659b-0758-4a7f-816e-91bee18df634",
"version": 1,
"metadata": {
"timestamp": "2022-03-08T12:30:39Z",
"tools": [
{
"vendor": "anchore",
"name": "syft",
"version": "[not provided]"
}
],
"component": {
"bom-ref": "163686ac6e30c752",
"type": "file",
"name": "/some/path"
}
},
"components": [
{
"type": "library",
"name": "package-1",
"version": "1.0.1",
"licenses": [
{
"license": {
"id": "MIT"
}
}
],
"cpe": "cpe:2.3:*:some:package:2:*:*:*:*:*:*:*",
"purl": "a-purl-2",
"properties": [
{
"name": "syft:package:foundBy",
"value": "the-cataloger-1"
},
{
"name": "syft:package:language",
"value": "python"
},
{
"name": "syft:package:metadataType",
"value": "PythonPackageMetadata"
},
{
"name": "syft:package:type",
"value": "python"
},
{
"name": "syft:location:0:path",
"value": "/some/path/pkg1"
}
]
},
{
"type": "library",
"name": "package-2",
"version": "2.0.1",
"cpe": "cpe:2.3:*:some:package:2:*:*:*:*:*:*:*",
"purl": "a-purl-2",
"properties": [
{
"name": "syft:package:foundBy",
"value": "the-cataloger-2"
},
{
"name": "syft:package:metadataType",
"value": "DpkgMetadata"
},
{
"name": "syft:package:type",
"value": "deb"
},
{
"name": "syft:location:0:path",
"value": "/some/path/pkg1"
},
{
"name": "syft:metadata:installedSize",
"value": "0"
}
]
},
{
"type": "operating-system",
"name": "debian",
"version": "1.2.3",
"description": "debian",
"swid": {
"tagId": "debian",
"name": "debian",
"version": "1.2.3"
},
"properties": [
{
"name": "syft:distro:id",
"value": "debian"
},
{
"name": "syft:distro:idLike:0",
"value": "like!"
},
{
"name": "syft:distro:prettyName",
"value": "debian"
},
{
"name": "syft:distro:versionID",
"value": "1.2.3"
}
]
}
]
}
@@ -0,0 +1,126 @@
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"serialNumber": "urn:uuid:342c3d2c-d26e-47b6-94d6-92fbf41da945",
"version": 1,
"metadata": {
"timestamp": "2022-03-08T12:30:39Z",
"tools": [
{
"vendor": "anchore",
"name": "syft",
"version": "[not provided]"
}
],
"component": {
"bom-ref": "711095b1cdf90cce",
"type": "container",
"name": "user-image-input",
"version": "sha256:2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368"
}
},
"components": [
{
"type": "library",
"name": "package-1",
"version": "1.0.1",
"licenses": [
{
"license": {
"id": "MIT"
}
}
],
"cpe": "cpe:2.3:*:some:package:1:*:*:*:*:*:*:*",
"purl": "a-purl-1",
"properties": [
{
"name": "syft:package:foundBy",
"value": "the-cataloger-1"
},
{
"name": "syft:package:language",
"value": "python"
},
{
"name": "syft:package:metadataType",
"value": "PythonPackageMetadata"
},
{
"name": "syft:package:type",
"value": "python"
},
{
"name": "syft:location:0:layerID",
"value": "sha256:16e64541f2ddf59a90391ce7bb8af90313f7d373f2105d88f3d3267b72e0ebab"
},
{
"name": "syft:location:0:path",
"value": "/somefile-1.txt"
}
]
},
{
"type": "library",
"name": "package-2",
"version": "2.0.1",
"cpe": "cpe:2.3:*:some:package:2:*:*:*:*:*:*:*",
"purl": "a-purl-2",
"properties": [
{
"name": "syft:package:foundBy",
"value": "the-cataloger-2"
},
{
"name": "syft:package:metadataType",
"value": "DpkgMetadata"
},
{
"name": "syft:package:type",
"value": "deb"
},
{
"name": "syft:location:0:layerID",
"value": "sha256:de6c235f76ea24c8503ec08891445b5d6a8bdf8249117ed8d8b0b6fb3ebe4f67"
},
{
"name": "syft:location:0:path",
"value": "/somefile-2.txt"
},
{
"name": "syft:metadata:installedSize",
"value": "0"
}
]
},
{
"type": "operating-system",
"name": "debian",
"version": "1.2.3",
"description": "debian",
"swid": {
"tagId": "debian",
"name": "debian",
"version": "1.2.3"
},
"properties": [
{
"name": "syft:distro:id",
"value": "debian"
},
{
"name": "syft:distro:idLike:0",
"value": "like!"
},
{
"name": "syft:distro:prettyName",
"value": "debian"
},
{
"name": "syft:distro:versionID",
"value": "1.2.3"
}
]
}
]
}