mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
Add dependencies to cyclonedx (#768)
Add dependencies to cyclonedx Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com> Co-authored-by: hectorj2f <hectorf@vmware.com>
This commit is contained in:
parent
161fa7be4a
commit
024a5a9f3f
@ -5,7 +5,9 @@ import (
|
||||
|
||||
"github.com/CycloneDX/cyclonedx-go"
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/internal/version"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/linux"
|
||||
"github.com/anchore/syft/syft/sbom"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
@ -29,6 +31,12 @@ func ToFormatModel(s sbom.SBOM) *cyclonedx.BOM {
|
||||
}
|
||||
components = append(components, toOSComponent(s.Artifacts.LinuxDistribution)...)
|
||||
cdxBOM.Components = &components
|
||||
|
||||
dependencies := toDependencies(s.Relationships)
|
||||
if len(dependencies) > 0 {
|
||||
cdxBOM.Dependencies = &dependencies
|
||||
}
|
||||
|
||||
return cdxBOM
|
||||
}
|
||||
|
||||
@ -97,18 +105,66 @@ func toBomDescriptor(name, version string, srcMetadata source.Metadata) *cyclone
|
||||
}
|
||||
}
|
||||
|
||||
// used to indicate that a relationship listed under the syft artifact package can be represented as a cyclonedx dependency.
|
||||
// NOTE: CycloneDX provides the ability to describe components and their dependency on other components.
|
||||
// The dependency graph is capable of representing both direct and transitive relationships.
|
||||
// If a relationship is either direct or transitive it can be included in this function.
|
||||
// An example of a relationship to not include would be: OwnershipByFileOverlapRelationship.
|
||||
func isExpressiblePackageRelationship(ty artifact.RelationshipType) bool {
|
||||
switch ty {
|
||||
case artifact.RuntimeDependencyOfRelationship:
|
||||
return true
|
||||
case artifact.DevDependencyOfRelationship:
|
||||
return true
|
||||
case artifact.BuildDependencyOfRelationship:
|
||||
return true
|
||||
case artifact.DependencyOfRelationship:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func toDependencies(relationships []artifact.Relationship) []cyclonedx.Dependency {
|
||||
result := make([]cyclonedx.Dependency, 0)
|
||||
for _, r := range relationships {
|
||||
exists := isExpressiblePackageRelationship(r.Type)
|
||||
if !exists {
|
||||
log.Warnf("unable to convert relationship from CycloneDX 1.3 JSON, dropping: %+v", r)
|
||||
continue
|
||||
}
|
||||
|
||||
innerDeps := []cyclonedx.Dependency{}
|
||||
innerDeps = append(innerDeps, cyclonedx.Dependency{Ref: string(r.From.ID())})
|
||||
result = append(result, cyclonedx.Dependency{
|
||||
Ref: string(r.To.ID()),
|
||||
Dependencies: &innerDeps,
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func toBomDescriptorComponent(srcMetadata source.Metadata) *cyclonedx.Component {
|
||||
switch srcMetadata.Scheme {
|
||||
case source.ImageScheme:
|
||||
bomRef, err := artifact.IDByHash(srcMetadata.ImageMetadata.ID)
|
||||
if err != nil {
|
||||
log.Warnf("unable to get fingerprint of image metadata=%s: %+v", srcMetadata.ImageMetadata.ID, err)
|
||||
}
|
||||
return &cyclonedx.Component{
|
||||
BOMRef: string(bomRef),
|
||||
Type: cyclonedx.ComponentTypeContainer,
|
||||
Name: srcMetadata.ImageMetadata.UserInput,
|
||||
Version: srcMetadata.ImageMetadata.ManifestDigest,
|
||||
}
|
||||
case source.DirectoryScheme, source.FileScheme:
|
||||
bomRef, err := artifact.IDByHash(srcMetadata.Path)
|
||||
if err != nil {
|
||||
log.Warnf("unable to get fingerprint of source metadata path=%s: %+v", srcMetadata.Path, err)
|
||||
}
|
||||
return &cyclonedx.Component{
|
||||
Type: cyclonedx.ComponentTypeFile,
|
||||
Name: srcMetadata.Path,
|
||||
BOMRef: string(bomRef),
|
||||
Type: cyclonedx.ComponentTypeFile,
|
||||
Name: srcMetadata.Path,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -37,5 +37,8 @@ func cycloneDxRedactor(s []byte) []byte {
|
||||
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
|
||||
}
|
||||
|
||||
@ -38,5 +38,13 @@ func cycloneDxRedactor(s []byte) []byte {
|
||||
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
|
||||
bomRefPattern := regexp.MustCompile(` bom-ref="[a-zA-Z0-9\-:]+"`)
|
||||
bomRef3339Pattern := 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]))`)
|
||||
for _, pattern := range []*regexp.Regexp{bomRefPattern, bomRef3339Pattern} {
|
||||
s = pattern.ReplaceAll(s, []byte(""))
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
@ -9,6 +9,18 @@ const (
|
||||
|
||||
// ContainsRelationship (supports any-to-any linkages) is a proxy for the SPDX 2.2 CONTAINS relationship.
|
||||
ContainsRelationship RelationshipType = "contains"
|
||||
|
||||
// RuntimeDependencyOfRelationship is a proxy for the SPDX 2.2.1 RUNTIME_DEPENDENCY_OF relationship.
|
||||
RuntimeDependencyOfRelationship RelationshipType = "runtime-dependency-of"
|
||||
|
||||
// DevDependencyOfRelationship is a proxy for the SPDX 2.2.1 DEV_DEPENDENCY_OF relationship.
|
||||
DevDependencyOfRelationship RelationshipType = "dev-dependency-of"
|
||||
|
||||
// BuildDependencyOfRelationship is a proxy for the SPDX 2.2.1 BUILD_DEPENDENCY_OF relationship.
|
||||
BuildDependencyOfRelationship RelationshipType = "build-dependency-of"
|
||||
|
||||
// DependencyOfRelationship is a proxy for the SPDX 2.2.1 DEPENDENCY_OF relationship.
|
||||
DependencyOfRelationship RelationshipType = "dependency-of"
|
||||
)
|
||||
|
||||
type RelationshipType string
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user