mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-02-21 19:48:53 +02:00
Fix SBOM component generation (#3958)
* Further improve library types * Fix translate * Added debug output * Enhance data * Added debug output * Fix code * Added test * Fix test
This commit is contained in:
parent
374cdb777b
commit
21416d82ed
@ -585,16 +585,20 @@ func checkSecurityViolations(ctx context.Context, config *ScanOptions, scan *ws.
|
||||
allLibraries := []ws.Library{}
|
||||
for _, project := range scan.ScannedProjects() {
|
||||
// collect errors and aggregate vulnerabilities from all projects
|
||||
if vulCount, alerts, err := checkProjectSecurityViolations(config, cvssSeverityLimit, project, sys, assessments, influx); err != nil {
|
||||
allAlerts = append(allAlerts, alerts...)
|
||||
vulnerabilitiesCount += vulCount
|
||||
vulCount, alerts, err := checkProjectSecurityViolations(config, cvssSeverityLimit, project, sys, assessments, influx)
|
||||
if err != nil {
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
}
|
||||
allAlerts = append(allAlerts, alerts...)
|
||||
vulnerabilitiesCount += vulCount
|
||||
|
||||
// collect all libraries detected in all related projects and errors
|
||||
if libraries, err := sys.GetProjectHierarchy(project.Token, true); err != nil {
|
||||
allLibraries = append(allLibraries, libraries...)
|
||||
libraries, err := sys.GetProjectHierarchy(project.Token, true)
|
||||
if err != nil {
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
}
|
||||
log.Entry().Debugf("Collected %v libraries for project %v", len(libraries), project.Name)
|
||||
allLibraries = append(allLibraries, libraries...)
|
||||
}
|
||||
log.Entry().Debugf("Aggregated %v alerts for scanned projects", len(allAlerts))
|
||||
|
||||
|
@ -379,8 +379,9 @@ func CreateCycloneSBOM(scan *Scan, libraries *[]Library, alerts *[]Alert) ([]byt
|
||||
|
||||
components := []cdx.Component{}
|
||||
flatUniqueLibrariesMap := map[string]Library{}
|
||||
transformToUniqueFlatList(libraries, &flatUniqueLibrariesMap)
|
||||
transformToUniqueFlatList(libraries, &flatUniqueLibrariesMap, 1)
|
||||
flatUniqueLibraries := piperutils.Values(flatUniqueLibrariesMap)
|
||||
log.Entry().Debugf("Got %v unique libraries in condensed flat list", len(flatUniqueLibraries))
|
||||
sort.Slice(flatUniqueLibraries, func(i, j int) bool {
|
||||
return flatUniqueLibraries[i].ToPackageUrl().ToString() < flatUniqueLibraries[j].ToPackageUrl().ToString()
|
||||
})
|
||||
@ -395,6 +396,7 @@ func CreateCycloneSBOM(scan *Scan, libraries *[]Library, alerts *[]Alert) ([]byt
|
||||
Name: lib.ArtifactID,
|
||||
Version: lib.Version,
|
||||
PackageURL: purl.ToString(),
|
||||
Hashes: &[]cdx.Hash{{Algorithm: cdx.HashAlgoSHA1, Value: lib.Sha1}},
|
||||
}
|
||||
components = append(components, component)
|
||||
}
|
||||
@ -513,7 +515,8 @@ func WriteCycloneSBOM(sbom []byte, utils piperutils.FileUtils) ([]piperutils.Pat
|
||||
return paths, nil
|
||||
}
|
||||
|
||||
func transformToUniqueFlatList(libraries *[]Library, flatMapRef *map[string]Library) {
|
||||
func transformToUniqueFlatList(libraries *[]Library, flatMapRef *map[string]Library, level int) {
|
||||
log.Entry().Debugf("Got %v libraries reported on level %v", len(*libraries), level)
|
||||
for _, lib := range *libraries {
|
||||
key := lib.ToPackageUrl().ToString()
|
||||
flatMap := *flatMapRef
|
||||
@ -521,7 +524,7 @@ func transformToUniqueFlatList(libraries *[]Library, flatMapRef *map[string]Libr
|
||||
if lookup.KeyID != lib.KeyID {
|
||||
flatMap[key] = lib
|
||||
if len(lib.Dependencies) > 0 {
|
||||
transformToUniqueFlatList(&lib.Dependencies, flatMapRef)
|
||||
transformToUniqueFlatList(&lib.Dependencies, flatMapRef, level+1)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -273,7 +273,6 @@ func TestWriteSarifFile(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCountSecurityVulnerabilities(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
alerts := []Alert{
|
||||
{Vulnerability: Vulnerability{CVSS3Score: 7.1}},
|
||||
|
12
pkg/whitesource/testdata/sbom.golden
vendored
12
pkg/whitesource/testdata/sbom.golden
vendored
@ -17,24 +17,36 @@
|
||||
<author>apache-commons</author>
|
||||
<name>commons-lang</name>
|
||||
<version>2.4.30</version>
|
||||
<hashes>
|
||||
<hash alg="SHA-1"></hash>
|
||||
</hashes>
|
||||
<purl>pkg:maven/apache-commons/commons-lang@2.4.30</purl>
|
||||
</component>
|
||||
<component bom-ref="pkg:maven/apache-commons/commons-lang@3.15" type="library">
|
||||
<author>apache-commons</author>
|
||||
<name>commons-lang</name>
|
||||
<version>3.15</version>
|
||||
<hashes>
|
||||
<hash alg="SHA-1"></hash>
|
||||
</hashes>
|
||||
<purl>pkg:maven/apache-commons/commons-lang@3.15</purl>
|
||||
</component>
|
||||
<component bom-ref="pkg:maven/apache-logging/log4j@1.14" type="library">
|
||||
<author>apache-logging</author>
|
||||
<name>log4j</name>
|
||||
<version>1.14</version>
|
||||
<hashes>
|
||||
<hash alg="SHA-1"></hash>
|
||||
</hashes>
|
||||
<purl>pkg:maven/apache-logging/log4j@1.14</purl>
|
||||
</component>
|
||||
<component bom-ref="pkg:maven/apache-logging/log4j@3.25" type="library">
|
||||
<author>apache-logging</author>
|
||||
<name>log4j</name>
|
||||
<version>3.25</version>
|
||||
<hashes>
|
||||
<hash alg="SHA-1"></hash>
|
||||
</hashes>
|
||||
<purl>pkg:maven/apache-logging/log4j@3.25</purl>
|
||||
</component>
|
||||
</components>
|
||||
|
@ -92,22 +92,32 @@ func transformLibToPurlType(libType string) string {
|
||||
log.Entry().Debugf("LibType reported as %v", libType)
|
||||
switch strings.ToLower(libType) {
|
||||
case "java":
|
||||
fallthrough
|
||||
case "maven_artifact":
|
||||
return packageurl.TypeMaven
|
||||
case "javascript/node.js":
|
||||
fallthrough
|
||||
case "node_packaged_module":
|
||||
return packageurl.TypeNPM
|
||||
case "javascript/bower":
|
||||
return "bower"
|
||||
case "go":
|
||||
fallthrough
|
||||
case "go_package":
|
||||
return packageurl.TypeGolang
|
||||
case "python":
|
||||
fallthrough
|
||||
case "python_package":
|
||||
return packageurl.TypePyPi
|
||||
case "debian":
|
||||
fallthrough
|
||||
case "debian_package":
|
||||
return packageurl.TypeDebian
|
||||
case "docker":
|
||||
return packageurl.TypeDocker
|
||||
case "source library":
|
||||
return "src"
|
||||
case ".net":
|
||||
fallthrough
|
||||
case "dot_net_resource":
|
||||
return packageurl.TypeNuget
|
||||
}
|
||||
return packageurl.TypeGeneric
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
||||
"github.com/package-url/packageurl-go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@ -295,6 +296,32 @@ func TestGetProductName(t *testing.T) {
|
||||
assert.Equal(t, "Test Product", productName)
|
||||
}
|
||||
|
||||
func TestTransformLibToPurlType(t *testing.T) {
|
||||
tt := []struct {
|
||||
libType string
|
||||
expected string
|
||||
}{
|
||||
{libType: "Java", expected: packageurl.TypeMaven},
|
||||
{libType: "MAVEN_ARTIFACT", expected: packageurl.TypeMaven},
|
||||
{libType: "javascript/Node.js", expected: packageurl.TypeNPM},
|
||||
{libType: "node_packaged_module", expected: packageurl.TypeNPM},
|
||||
{libType: "javascript/bower", expected: "bower"},
|
||||
{libType: "go", expected: packageurl.TypeGolang},
|
||||
{libType: "go_package", expected: packageurl.TypeGolang},
|
||||
{libType: "python", expected: packageurl.TypePyPi},
|
||||
{libType: "python_package", expected: packageurl.TypePyPi},
|
||||
{libType: "debian", expected: packageurl.TypeDebian},
|
||||
{libType: "debian_package", expected: packageurl.TypeDebian},
|
||||
{libType: "docker", expected: packageurl.TypeDocker},
|
||||
{libType: ".net", expected: packageurl.TypeNuget},
|
||||
{libType: "dot_net_resource", expected: packageurl.TypeNuget},
|
||||
}
|
||||
|
||||
for i, test := range tt {
|
||||
assert.Equalf(t, test.expected, transformLibToPurlType(test.libType), "run %v failed", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetProjectHierarchy(t *testing.T) {
|
||||
myTestClient := whitesourceMockClient{
|
||||
responseBody: `{
|
||||
@ -411,7 +438,10 @@ func TestGetProjectHierarchy(t *testing.T) {
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"warningMessages":[
|
||||
"Invalid input: orgToken"
|
||||
]
|
||||
}`,
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user